#35359: Got `django.core.exceptions.FieldError` when adding GeneratedField
--------------------------------------+--------------------------------
               Reporter:  wd0517      |          Owner:  nobody
                   Type:  Bug         |         Status:  new
              Component:  Migrations  |        Version:  5.0
               Severity:  Normal      |       Keywords:  GeneratedField
           Triage Stage:  Unreviewed  |      Has patch:  0
    Needs documentation:  0           |    Needs tests:  0
Patch needs improvement:  0           |  Easy pickings:  0
                  UI/UX:  0           |
--------------------------------------+--------------------------------
 Here is an exists model

 {{{
 class Foo1(models.Model):
     age = models.IntegerField()
 }}}

 Then adding GeneratedField


 {{{
 class Foo1(models.Model):
     age = models.IntegerField()
     name = models.CharField(max_length=10)
     lower_name = models.GeneratedField(
         expression=Lower("name"),
         output_field=models.CharField(max_length=11),
         db_persist=True,
     )
 }}}

 Run makemigrations get below file


 {{{
 class Migration(migrations.Migration):

     dependencies = [
         ('temp_django_test', '0006_foo1'),
     ]

     operations = [
         migrations.AddField(
             model_name='foo1',
             name='lower_name',
             field=models.GeneratedField(db_persist=True,
 expression=django.db.models.functions.text.Lower('name'),
 output_field=models.CharField(max_length=11)),
         ),
         migrations.AddField(
             model_name='foo1',
             name='name',
             field=models.CharField(default='a', max_length=10),
             preserve_default=False,
         ),
     ]
 }}}


 Then run migrate, will got error


 {{{
 temp-django-5.0 ❯ python manage.py migrate
 Operations to perform:
   Apply all migrations: admin, auth, contenttypes, sessions,
 temp_django_test
 Running migrations:
   Applying temp_django_test.0007_foo1_lower_name_foo1_name...Traceback
 (most recent call last):
   File "/Users/wangdi/Desktop/test_scripts.nosync/temp-
 django-5.0/manage.py", line 22, in <module>
     main()
   File "/Users/wangdi/Desktop/test_scripts.nosync/temp-
 django-5.0/manage.py", line 18, in main
     execute_from_command_line(sys.argv)
   File "/Users/wangdi/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/core/management/__init__.py", line 442, in
 execute_from_command_line
     utility.execute()
   File "/Users/wangdi/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/core/management/__init__.py", line 436, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/Users/wangdi/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/core/management/base.py", line 413, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/core/management/base.py", line 459, in execute
     output = self.handle(*args, **options)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/core/management/base.py", line 107, in wrapper
     res = handle_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/core/management/commands/migrate.py", line 356, in handle
     post_migrate_state = executor.migrate(
                          ^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/migrations/executor.py", line 135, in migrate
     state = self._migrate_all_forwards(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/migrations/executor.py", line 167, in
 _migrate_all_forwards
     state = self.apply_migration(
             ^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/migrations/executor.py", line 252, in apply_migration
     state = migration.apply(state, schema_editor)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/migrations/migration.py", line 132, in apply
     operation.database_forwards(
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/migrations/operations/fields.py", line 108, in
 database_forwards
     schema_editor.add_field(
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/backends/mysql/schema.py", line 103, in add_field
     super().add_field(model, field)
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 709, in add_field
     definition, params = self.column_sql(model, field,
 include_default=True)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 369, in column_sql
     " ".join(
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 336, in _iter_column_sql
     generated_sql, generated_params = self._column_generated_sql(field)
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/backends/base/schema.py", line 434, in
 _column_generated_sql
     expression_sql, params = field.generated_sql(self.connection)
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/models/fields/generated.py", line 58, in generated_sql
     resolved_expression = self.expression.resolve_expression(
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/models/expressions.py", line 975, in resolve_expression
     c.source_expressions[pos] = arg.resolve_expression(
                                 ^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/models/expressions.py", line 854, in resolve_expression
     return query.resolve_ref(self.name, allow_joins, reuse, summarize)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/models/sql/query.py", line 2014, in resolve_ref
     join_info = self.setup_joins(
                 ^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/models/sql/query.py", line 1867, in setup_joins
     path, final_field, targets, rest = self.names_to_path(
                                        ^^^^^^^^^^^^^^^^^^^
   File "/Users/wd0517/Desktop/test_scripts.nosync/temp-
 django-5.0/.venv/lib/python3.11/site-
 packages/django/db/models/sql/query.py", line 1772, in names_to_path
     raise FieldError(
 django.core.exceptions.FieldError: Cannot resolve keyword 'name' into
 field. Choices are: age, id, lower_name
 }}}

 Environment:
 - Python 3.11.8
 - Django 5.0.4
 - MySQL 8.0.34

 I think the bug is caused by the order of operations in Migration, after
 adjusting it, then can be migrate successfully
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35359>
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/0107018eb68786a7-aecb9f06-b19e-45b0-9f68-960616e707f5-000000%40eu-central-1.amazonses.com.

Reply via email to