Ошибка уникального ограничения в Upsert при вызове Bulk_create с update_conficts

Я столкнулся с ошибкой уникального ограничения в django. Целью API является создание или обновление оценок учащегося на основе вариации предмета, результатов экзамена и в массовом порядке. Для этого я использовал массовое создание с флагом конфликтов обновлений.

Вот актуальная модель

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.

Я предположил, что это потому, что не было предусмотрено никаких ограничений, гласящих, что эти поля должны быть уникальными вместе, поэтому я добавил ограничение в модель меток.

class Meta:
    constraints = [
        models.UniqueConstraint(
            fields=["subject_variation", "exam_results"], name = "unique_marks"
        )
    ]

После того, как я выполняю миграцию и мигрирую, аспект массового создания работает и создает два новых экземпляра меток. Вот полезная нагрузка для справки.

 {
    "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."
            ]
        }
    ]
}

Предполагается, что он обновляется, если существуют эти уникальные ограничения, но я получаю эту ошибку. Как с этим справиться? Если я закомментирую ограничения модели, она снова заработает. Это работает даже при создании новых экземпляров. Это работает до тех пор, пока я не сделаю миграцию и не перенесу ее снова, поскольку метакласс модели изменится. Затем он возвращается к той же ошибке.

Спасибо.

Прямо перед вызовом вставки выполняется следующий запрос: SELECT 1 AS "a" FROM "academics_marks" WHERE ("accademics_marks"."is_active" AND "academics_marks"."exam_results_id" = 1 AND "academics_marks"."subject_variation_id" = 2) ПРЕДЕЛ 1; арг=(1, 1, 2); alias=default, это вызывает ошибку. Как мне обойти это?

OzoneBht 02.07.2024 12:36
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это было исправлено путем отключения валидаторов в среде отдыха django.

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```

Другие вопросы по теме