#34928: makemigrations when adding a ForeignKey to a model with a 
UniqueConstraint
must create the field before creating the constraint
------------------------------------------+------------------------
               Reporter:  yonatanramirez  |          Owner:  nobody
                   Type:  Bug             |         Status:  new
              Component:  Migrations      |        Version:  4.2
               Severity:  Normal          |       Keywords:
           Triage Stage:  Unreviewed      |      Has patch:  0
    Needs documentation:  0               |    Needs tests:  0
Patch needs improvement:  0               |  Easy pickings:  0
                  UI/UX:  0               |
------------------------------------------+------------------------
 This issue looks like #25551 but with UniqueConstraint and not
 unique_together.


 {{{#!diff
 from django.db import models

 +class Author(models.Model):
 +    name = models.CharField(max_length=255)
 +
  class Book(models.Model):
      name = models.CharField(max_length=255)
 +    author = models.ForeignKey(Author, on_delete=models.CASCADE,
 null=True)
 +
 +    class Meta:
 +        constraints = [
 +            models.UniqueConstraint(
 +                fields=['name', 'author'],
 +                name='unique_book_name_author'
 +            )
 +        ]
 }}}

 This is the output of the makemigration command
 {{{
 Migrations for 'issue':
   issue/migrations/0002_author_book_unique_book_name_author_book_author.py
     - Create model Author
     - Create constraint unique_book_name_author on model book
     - Add field author to book
 }}}

 And the portion of the migration file:
 {{{
 operations = [
         migrations.CreateModel(
             name='Author',
             fields=[
                 ('id', models.BigAutoField(auto_created=True,
 primary_key=True, serialize=False, verbose_name='ID')),
                 ('name', models.CharField(max_length=255)),
             ],
         ),
         migrations.AddConstraint(
             model_name='book',
             constraint=models.UniqueConstraint(fields=('name', 'author'),
 name='unique_book_name_author'),
         ),
         migrations.AddField(
             model_name='book',
             name='author',
             field=models.ForeignKey(null=True,
 on_delete=django.db.models.deletion.CASCADE, to='issue.author'),
         ),
     ]
 }}}

 The stacktrace:
 {{{
 Operations to perform:
   Apply all migrations: admin, auth, contenttypes, issue, sessions
 Running migrations:
   Applying contenttypes.0001_initial... OK
   Applying auth.0001_initial... OK
   Applying admin.0001_initial... OK
   Applying admin.0002_logentry_remove_auto_add... OK
   Applying admin.0003_logentry_add_action_flag_choices... OK
   Applying contenttypes.0002_remove_content_type_name... OK
   Applying auth.0002_alter_permission_name_max_length... OK
   Applying auth.0003_alter_user_email_max_length... OK
   Applying auth.0004_alter_user_username_opts... OK
   Applying auth.0005_alter_user_last_login_null... OK
   Applying auth.0006_require_contenttypes_0002... OK
   Applying auth.0007_alter_validators_add_error_messages... OK
   Applying auth.0008_alter_user_username_max_length... OK
   Applying auth.0009_alter_user_last_name_max_length... OK
   Applying auth.0010_alter_group_name_max_length... OK
   Applying auth.0011_update_proxy_permissions... OK
   Applying auth.0012_alter_user_first_name_max_length... OK
   Applying issue.0001_initial... OK
   Applying
 issue.0002_author_book_unique_book_name_author_book_author...Traceback
 (most recent call last):
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/models/options.py", line 681, in get_field
     return self.fields_map[field_name]
            ~~~~~~~~~~~~~~~^^^^^^^^^^^^
 KeyError: 'author'

 During handling of the above exception, another exception occurred:

 Traceback (most recent call last):
   File "/home/yramirez/playground/django/essai/manage.py", line 22, in
 <module>
     main()
   File "/home/yramirez/playground/django/essai/manage.py", line 18, in
 main
     execute_from_command_line(sys.argv)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/core/management/__init__.py", line 442, in
 execute_from_command_line
     utility.execute()
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/core/management/__init__.py", line 436, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/core/management/base.py", line 412, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/core/management/base.py", line 458, in execute
     output = self.handle(*args, **options)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/core/management/base.py", line 106, in wrapper
     res = handle_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/core/management/commands/migrate.py", line 356, in handle
     post_migrate_state = executor.migrate(
                          ^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/migrations/executor.py", line 135, in migrate
     state = self._migrate_all_forwards(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/migrations/executor.py", line 167, in
 _migrate_all_forwards
     state = self.apply_migration(
             ^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/migrations/executor.py", line 252, in apply_migration
     state = migration.apply(state, schema_editor)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/migrations/migration.py", line 132, in apply
     operation.database_forwards(
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/migrations/operations/models.py", line 1135, in
 database_forwards
     schema_editor.add_constraint(model, self.constraint)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/backends/sqlite3/schema.py", line 562, in
 add_constraint
     self._remake_table(model)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/backends/sqlite3/schema.py", line 331, in _remake_table
     self.create_model(new_model)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 448, in create_model
     sql, params = self.table_sql(model)
                   ^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 267, in table_sql
     constraints = [
                   ^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 268, in <listcomp>
     constraint.constraint_sql(model, self)
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/models/constraints.py", line 216, in constraint_sql
     fields = [model._meta.get_field(field_name) for field_name in
 self.fields]
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/models/constraints.py", line 216, in <listcomp>
     fields = [model._meta.get_field(field_name) for field_name in
 self.fields]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/yramirez/.pyenv/versions/django/lib/python3.11/site-
 packages/django/db/models/options.py", line 683, in get_field
     raise FieldDoesNotExist(
 django.core.exceptions.FieldDoesNotExist: NewBook has no field named
 'author'
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34928>
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018b6c9d228e-b0af6c53-670d-4aa3-abe2-b47d20039903-000000%40eu-central-1.amazonses.com.

Reply via email to