#31834: Cannot sqlmigrate on Django migrations that change unique_together
-------------------------------------+-------------------------------------
     Reporter:  Brіаn Lаі            |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  3.0
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  sqlmigrate           |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Brіаn Lаі:

Old description:

> Somewhat similar to #26624, but forward sqlmigrate, reproduced on Django
> 3.0.8 and Postgres 10.x.
>
> If a model has a unique_together of
>
> {{{
> unique_together = [
>     (a, b)
> ]
> }}}
>
> and it becomes
>
> {{{
> unique_together = [
>     (a, b, c)
> ]
> }}}
>
> , although the makemigrations command successfully generates a new
> migration with the corresponding AlterUniqueTogether() operation, the
> migration cannot be inspected with the sqlmigrate command.
>

> Reproduce bug with the following (the project may also be attached)
>
> {{{
> class Model1(models.Model):
>     id = models.IntegerField(primary_key=True)
>     name = models.CharField(max_length=255, unique=True)
>

> class Model2(models.Model):
>     id = models.IntegerField(primary_key=True)
>     link_id = models.CharField(max_length=255)
>     settings = models.ForeignKey(Model1, on_delete=models.CASCADE)
>

> class Model3(models.Model):
>     id = models.IntegerField(primary_key=True)
>     order = models.IntegerField()
>     model_2 = models.ForeignKey(Model2, on_delete=models.CASCADE)
>     direct = models.BooleanField(default=True)
>
>     class Meta:
>         unique_together = [
>             ('model_2', 'order')
>             # To get the bug, change this to ('model_2', 'order',
> 'direct') and sqlmigrate the migration that this creates.
>         ]
> }}}

New description:

 Somewhat similar to #26624, but forward sqlmigrate, reproduced on Django
 3.0.8 and Postgres 10.x.

 If a model has a unique_together of

 {{{
 unique_together = [
     (a, b)
 ]
 }}}

 and it becomes

 {{{
 unique_together = [
     (a, b, c)
 ]
 }}}

 , although the makemigrations command successfully generates a new
 migration with the corresponding AlterUniqueTogether() operation, the
 migration cannot be inspected with the sqlmigrate command.


 Reproduce bug with the following (the project may also be attached)

 {{{
 class Model1(models.Model):
     id = models.IntegerField(primary_key=True)
     name = models.CharField(max_length=255, unique=True)


 class Model2(models.Model):
     id = models.IntegerField(primary_key=True)
     link_id = models.CharField(max_length=255)
     settings = models.ForeignKey(Model1, on_delete=models.CASCADE)


 class Model3(models.Model):
     id = models.IntegerField(primary_key=True)
     order = models.IntegerField()
     model_2 = models.ForeignKey(Model2, on_delete=models.CASCADE)
     direct = models.BooleanField(default=True)

     class Meta:
         unique_together = [
             ('model_2', 'order')
             # To get the bug, change this to ('model_2', 'order',
 'direct') and sqlmigrate the migration that this creates.
         ]
 }}}

 The error shown in the terminal is:

 {{{
 Traceback (most recent call last):
   File "manage.py", line 22, in <module>
     execute_from_command_line(sys.argv)
   File "/lib/python3.6/site-packages/django/core/management/__init__.py",
 line 401, in execute_from_command_line
     utility.execute()
   File "/lib/python3.6/site-packages/django/core/management/__init__.py",
 line 395, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/lib/python3.6/site-packages/django/core/management/base.py", line
 328, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/lib/python3.6/site-
 packages/django/core/management/commands/sqlmigrate.py", line 30, in
 execute
     return super().execute(*args, **options)
   File "/lib/python3.6/site-packages/django/core/management/base.py", line
 369, in execute
     output = self.handle(*args, **options)
   File "/lib/python3.6/site-
 packages/django/core/management/commands/sqlmigrate.py", line 65, in
 handle
     sql_statements = executor.collect_sql(plan)
   File "/lib/python3.6/site-packages/django/db/migrations/executor.py",
 line 225, in collect_sql
     state = migration.apply(state, schema_editor, collect_sql=True)
   File "/lib/python3.6/site-packages/django/db/migrations/migration.py",
 line 124, in apply
     operation.database_forwards(self.app_label, schema_editor, old_state,
 project_state)
   File "/lib/python3.6/site-
 packages/django/db/migrations/operations/models.py", line 525, in
 database_forwards
     getattr(new_model._meta, self.option_name, set()),
   File "/lib/python3.6/site-packages/django/db/backends/base/schema.py",
 line 380, in alter_unique_together
     self._delete_composed_index(model, fields, {'unique': True},
 self.sql_delete_unique)
   File "/lib/python3.6/site-packages/django/db/backends/base/schema.py",
 line 414, in _delete_composed_index
     ", ".join(columns),
 ValueError: Found wrong number (0) of constraints for bar_model3(model_2,
 order)
 }}}

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31834#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/062.55fbfe8d6c92b9d4feb7797c72f5f0ca%40djangoproject.com.

Reply via email to