Im facing a unique constraint failed error with django. The objective of the api is, eithering creating or updating marks of the student, based on subject variation, exam_results and in bulk. For that, I've used bulk create with update conflicts flag.
Here is the current model
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):
now, when I do bulk create, it asks for unique fields, and since I only want to update marks if there is same exam results, subject variation and student in another instance. So, i add that to unique fields of bulk create.
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
but when I do this, it says there is no unique or exclusion constraint matching the ON CONFLICT specification.
I assumed its because there's no constraint thats been provided to say that those fields must be unique together, so I added a constraint on the marks model.
class Meta:
constraints = [
models.UniqueConstraint(
fields=["subject_variation", "exam_results"], name="unique_marks"
)
]
After i make migrations and migrate, the bulk create aspect works, and creates two new instance of marks. Here is the payload for reference.
{
"marks": [
{
"exam_results" : "1",
"subject_variation" : "1",
"marks_obtained" : 40,
},
{
"exam_results" : "1",
"subject_variation" : "2",
"marks_obtained" : 20,
}
]
}
Now, since I want to update the marks again, I should call this api again. However, I get the error:
{
"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."
]
}
]
}
It is supposed to be updating, if those unique constraints are there, but I get this error. How to deal with this? If i comment out the constraints from the model, it seems to work again. It even works when creating new instances. This is working until I makemigration and migrate again, as the meta class gets changed for the model. Then, it goes back to the same error.
Thank you.
It got fixed by disabling the validators in 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
by removing the default validators by overwriting with an empty array, the model validator got disabled preventing the following query:
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```