Unique Constraint Failed In Upsert When Calling bulk_create with update_conficts
Я сталкиваюсь с ошибкой unique constraint failed в django. Цель api - создание или обновление оценок ученика на основе вариации предмета, результатов экзамена и в массовом порядке. Для этого я использовал bulk create с флагом update conflicts.
Вот текущая модель
class Marks(Common):
exam_results = models.ForeignKey(
"ExamResults", on_delete=models.CASCADE, related_name="marks"
)
subject_variation = models.ForeignKey(
"SubjectVariation", on_delete=models.CASCADE, related_name="marks"
)
student = models.ForeignKey(
"Student", on_delete=models.CASCADE, related_name="marks"
)
marks_obtained = models.FloatField()
objects = BaseModelManager()class Marks(Common):
Теперь, когда я делаю массовое создание, оно запрашивает уникальные поля, а поскольку я хочу обновлять оценки только в том случае, если в другом экземпляре есть те же результаты экзамена, вариации предмета и студент. Поэтому я добавляю это в уникальные поля при массовом создании.
class MarksUpsertSerializer(serializers.ModelSerializer):
class Meta:
model = Marks
fields = ("exam_results", "subject_variation", "marks_obtained")
class BulkMarksUpsertSerializer(serializers.Serializer):
marks = MarksUpsertSerializer(many=True)
def create(self, validated_data):
marks = [Marks(**item) for item in validated_data["marks"]]
marks = Marks.objects.bulk_create(
marks,
update_conflicts=True,
update_fields=["marks_obtained"],
unique_fields=["exam_results", "subject_variation"],
)
return marks
но когда я делаю это, он говорит, что нет уникального или исключающего ограничения, соответствующего спецификации ON CONFLICT.
Я предположил, что это связано с тем, что нет ограничений, которые бы говорили, что эти поля должны быть уникальными вместе, поэтому я добавил ограничение на модель marks.
class Meta:
constraints = [
models.UniqueConstraint(
fields=["subject_variation", "exam_results"], name="unique_marks"
)
]
После того, как я сделал миграции и мигрировал, аспект bulk create работает и создает два новых экземпляра меток. Вот полезная нагрузка для справки.
{
"marks": [
{
"exam_results" : "1",
"subject_variation" : "1",
"marks_obtained" : 40,
},
{
"exam_results" : "1",
"subject_variation" : "2",
"marks_obtained" : 20,
}
]
}
Теперь, поскольку я хочу снова обновить метки, я должен снова вызвать этот api. Однако я получаю ошибку:
{
"marks": [
{
"non_field_errors": [
"The fields subject_variation, exam_results must make a unique set."
]
},
{
"non_field_errors": [
"The fields subject_variation, exam_results must make a unique set."
]
}
]
}
По идее, обновление должно происходить, если эти уникальные ограничения есть, но я получаю эту ошибку. Как с этим бороться? Если я закомментирую ограничения из модели, то все снова заработает. Это работает даже при создании новых экземпляров. Это работает до тех пор, пока я не сделаю миграцию и не мигрирую снова, поскольку мета-класс изменяется для модели. Затем снова возникает та же ошибка.
Спасибо.
Это было исправлено отключением валидаторов в django rest framework,
class MarksUpsertSerializer(serializers.ModelSerializer):
class Meta:
model = Marks
fields = ("exam_results", "subject_variation", "marks_obtained", "student")
class BulkMarksUpsertSerializer(serializers.Serializer):
marks = MarksUpsertSerializer(many=True, validators=[]) # <-- here
Удалив валидаторы по умолчанию путем перезаписи пустым массивом, валидатор модели отключился, предотвратив выполнение следующего запроса:
SELECT 1 AS "a" FROM "academics_marks" WHERE ("academics_marks"."is_active" AND "academics_marks"."exam_results_id" = 1 AND "academics_marks"."subject_variation_id" = 2) LIMIT 1; args=(1, 1, 2); alias=default```