#35199: Makemigrations raises KeyError when removing a field from
Meta.unique_together when its a list
-------------------------------------+-------------------------------------
     Reporter:  Paco Martínez        |                    Owner:  nobody
         Type:  Bug                  |                   Status:  closed
    Component:  Migrations           |                  Version:  4.2
     Severity:  Normal               |               Resolution:  invalid
     Keywords:  migrations,          |             Triage Stage:
  unique_together, makemigrations    |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Paco Martínez):

 * resolution:   => invalid
 * status:  new => closed


Old description:

> Having a model like this, with a **unique_together** with a **list of
> lists**:
>
> {{{
> from django.db import models
>
> class MyModel(models.Model):
>     field1 = models.CharField(max_length=50)
>     field2 = models.IntegerField()
>     field3 = models.DateField()
>
>     class Meta:
>         unique_together=[['field1', 'field2', 'field3']]
> }}}
>

> If we want to remove one of the fields from the constraint like:
>
> {{{
>     class Meta:
>         unique_together=[['field1', 'field2']]
> }}}
>
> When we run the ''makemigrations'' command, it raises a KeyError. This is
> the traceback:
> {{{
> Traceback (most recent call last):
>   File "/code/manage.py", line 26, in <module>
>     main()
>   File "/code/manage.py", line 22, in main
>     execute_from_command_line(sys.argv)
>   File "/usr/local/lib/python3.12/site-
> packages/django/core/management/__init__.py", line 442, in
> execute_from_command_line
>     utility.execute()
>   File "/usr/local/lib/python3.12/site-
> packages/django/core/management/__init__.py", line 436, in execute
>     self.fetch_command(subcommand).run_from_argv(self.argv)
>   File "/usr/local/lib/python3.12/site-
> packages/django/core/management/base.py", line 412, in run_from_argv
>     self.execute(*args, **cmd_options)
>   File "/usr/local/lib/python3.12/site-
> packages/django/core/management/base.py", line 458, in execute
>     output = self.handle(*args, **options)
>              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/usr/local/lib/python3.12/site-
> packages/django/core/management/base.py", line 106, in wrapper
>     res = handle_func(*args, **kwargs)
>           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/usr/local/lib/python3.12/site-
> packages/django/core/management/commands/makemigrations.py", line 233, in
> handle
>     changes = autodetector.changes(
>               ^^^^^^^^^^^^^^^^^^^^^
>   File "/usr/local/lib/python3.12/site-
> packages/django/db/migrations/autodetector.py", line 46, in changes
>     changes = self._detect_changes(convert_apps, graph)
>               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/usr/local/lib/python3.12/site-
> packages/django/db/migrations/autodetector.py", line 192, in
> _detect_changes
>     self.generate_removed_altered_unique_together()
>   File "/usr/local/lib/python3.12/site-
> packages/django/db/migrations/autodetector.py", line 1506, in
> generate_removed_altered_unique_together
> self._generate_removed_altered_foo_together(operations.AlterUniqueTogether)
>   File "/usr/local/lib/python3.12/site-
> packages/django/db/migrations/autodetector.py", line 1481, in
> _generate_removed_altered_foo_together
>     for (
>   File "/usr/local/lib/python3.12/site-
> packages/django/db/migrations/autodetector.py", line 1462, in
> _get_altered_foo_together_operations
>     field = new_model_state.get_field(field_name)
>             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/usr/local/lib/python3.12/site-
> packages/django/db/migrations/state.py", line 765, in get_field
>     return self.fields[field_name]
>            ~~~~~~~~~~~^^^^^^^^^^^^
> KeyError: 'field1'
>
> }}}
>
> This does NOT happen when the unique_together option is a **tuple**. It
> works as expected creating the migration.

New description:

 Having a model like this, with a **unique_together** with a **list of
 lists**:

 {{{
 from django.db import models

 class MyModel(models.Model):
     field1 = models.CharField(max_length=50)
     field2 = models.ForeignKey()
     field3 = models.ForeignKey()

     class Meta:
         unique_together=[['field1', 'field2', 'field3']]
 }}}


 If we want to remove one of the fields from the constraint like:

 {{{
     class Meta:
         unique_together=[['field1', 'field2']]
 }}}

 When we run the ''makemigrations'' command, it raises a KeyError. This is
 the traceback:
 {{{
 Traceback (most recent call last):
   File "/code/manage.py", line 26, in <module>
     main()
   File "/code/manage.py", line 22, in main
     execute_from_command_line(sys.argv)
   File "/usr/local/lib/python3.12/site-
 packages/django/core/management/__init__.py", line 442, in
 execute_from_command_line
     utility.execute()
   File "/usr/local/lib/python3.12/site-
 packages/django/core/management/__init__.py", line 436, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/usr/local/lib/python3.12/site-
 packages/django/core/management/base.py", line 412, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/usr/local/lib/python3.12/site-
 packages/django/core/management/base.py", line 458, in execute
     output = self.handle(*args, **options)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/site-
 packages/django/core/management/base.py", line 106, in wrapper
     res = handle_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/site-
 packages/django/core/management/commands/makemigrations.py", line 233, in
 handle
     changes = autodetector.changes(
               ^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/site-
 packages/django/db/migrations/autodetector.py", line 46, in changes
     changes = self._detect_changes(convert_apps, graph)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/site-
 packages/django/db/migrations/autodetector.py", line 192, in
 _detect_changes
     self.generate_removed_altered_unique_together()
   File "/usr/local/lib/python3.12/site-
 packages/django/db/migrations/autodetector.py", line 1506, in
 generate_removed_altered_unique_together
 self._generate_removed_altered_foo_together(operations.AlterUniqueTogether)
   File "/usr/local/lib/python3.12/site-
 packages/django/db/migrations/autodetector.py", line 1481, in
 _generate_removed_altered_foo_together
     for (
   File "/usr/local/lib/python3.12/site-
 packages/django/db/migrations/autodetector.py", line 1462, in
 _get_altered_foo_together_operations
     field = new_model_state.get_field(field_name)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/usr/local/lib/python3.12/site-
 packages/django/db/migrations/state.py", line 765, in get_field
     return self.fields[field_name]
            ~~~~~~~~~~~^^^^^^^^^^^^
 KeyError: 'field1'

 }}}

 This does NOT happen when the unique_together option is a **tuple**. It
 works as expected creating the migration.

--
Comment:

 Sorry but trying a bit more I discovered that the fields in the
 unique_together were named with the "_id" suffix as they are
 ForeignKeyFields. Don't know how the constraint is there for several
 months and working fine. Now it's enforcing to name the fields without the
 suffix.

 With that the makemigrations command runs as expected.

 Sorry for the inconvenience of creating the ticket.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35199#comment:1>
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/0107018dad35814c-53987fa0-3a17-4f44-9ec2-5d0166a631b2-000000%40eu-central-1.amazonses.com.

Reply via email to