Как внести изменения в ограничение unique_together из одного набора полей модели в другой в Django - PullRequest
0 голосов
/ 19 марта 2020

В моем Django проекте у меня есть следующая модель :

class TenderOrigin(models.Model):
    doc_type = models.CharField(max_length=2, ...)
    doc_short_txt = models.CharField(max_length=150, ...)
    create_date = models.DateField(default=timezone.now, ...)
    port_grp = models.ForeignKey(PortGroup, on_delete=models.CASCADE, null=True, ...)
#    frt_grp = models.ForeignKey(FrtGroup, on_delete=models.CASCADE, null=True, ...)
    locn_from = models.ForeignKey(Plant, on_delete=models.CASCADE, ...)
    tender_number = models.CharField(max_length=150, null=True,...)
    tender_date = models.DateField(null=True, ...)

    class Meta:
        ordering = ['locn_from__LocName']
#        unique_together = [['frt_grp', 'locn_from', 'tender_date'],]    # Original constraint
        unique_together = [['port_grp', 'locn_from', 'tender_date'],]    # New constraint being defined

Как отмечалось выше (против определения уникальных ограничений), я пытаюсь изменить оригинал уникальное_все ограничение на новое (используется поле port_grp). Это изменение вызвано новым полем (port_grp), которое добавляется в модель, а поле frt_grp удаляется.

Однако при переносе появляется следующее сообщение об ошибке:

...
...    
Traceback (most recent call last):
  File "manage.py", line 15, in <module>
    execute_from_command_line(sys.argv)
...
...
 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 303, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: matmovt_tenderorigin.port_grp_id, matmovt_tenderorigin.locn_from_id, matmovt_tenderorigin.tender_date

Можно ли изменить ограничение unique_together , как определено для одного набора полей , на другое (без удаления существующих данных)?

1 Ответ

0 голосов
/ 19 марта 2020

Вот как я подхожу к этому.

  1. Создайте новые поля, необходимые для вашей модели.
  2. Создайте миграцию для новых полей.
  3. Create миграция данных для заполнения новых полей
  4. Создайте UniqueConstraint и удалите старое уникальное ограничение.
  5. Создайте миграцию для изменений ограничения. Убедитесь, что падение происходит после создания. Хотя все это должно выполняться в транзакции, поэтому это не должно иметь значения.
  6. Удалить старые поля.

Если при переносе данных будут созданы данные, которые нарушают старое уникальное ограничение, то удалите что перед выполнением миграции данных. Очевидно, это довольно рискованно, потому что теперь вы позволяете самой системе генерировать данные, которые могут быть недействительными, что делает откат / обратный перенос очень болезненным.

...