Как отловить sql ошибку в Django сериале Rest Framework? - PullRequest
1 голос
/ 19 апреля 2020

У меня есть конечная точка Django Rest Framework, в которую внешняя сторона отправляет данные в довольно большом объеме. Поскольку он выполнял около 200 вставок в секунду, я проверил запросы, которые он делал. Я обнаружил, что он на самом деле сначала сделал запрос SELECT, чтобы проверить, был ли дублированный идентификатор. Поскольку я не думал, что будут какие-либо (или, по крайней мере, не так много) дубликаты ключей, я хотел отключить эту проверку. Поэтому я добавил эту строку в мой сериализатор:

id = serializers.UUIDField(validators=[])  # Disable the validators for the id, which improves performance (rps) by over 200%

И, как вы можете видеть в комментарии, это значительно повышает производительность. Тем не менее, одним из недостатков является то, что он выдает ошибку 500, если фактически опубликован дубликат ключа, говоря:

duplicate key value violates unique constraint

Как я смогу отловить эту ошибку базы данных и вернуть аккуратный ответ вместо броска эта ошибка 500?

1 Ответ

1 голос
/ 19 апреля 2020

Один из способов сделать это - переопределить метод create сериализатора, чтобы перехватить ошибку.

from django.db import IntegrityError
from django.core.exceptions import ValidationError

from rest_framework import serializers

class MySerializer(serializers.ModelSerializer):

    [ ... ]

    def create(self, validated_data):
        try:
            return super().create(validated_data)
        except IntegrityError as e:
            raise serializers.ValidationError(str(e))

Вам также необходимо переопределить update сериализатора, если разрешить PUT в объект.

Может быть лучше разместить крючок, в зависимости от вашего варианта использования. Он должен быть где-то на сериализаторе, а try-catch должен быть там, где вызывается метод объектов save(). Для вас это может помочь переопределить метод save() сериализатора примерно тем же кодом, что и выше.

...