#34546: Failed migration yields to unmigratable app:""OperationalError: (1050,
"Table '<name>' already exists")
------------------------------------------+------------------------
               Reporter:  Natalia Bidart  |          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               |
------------------------------------------+------------------------
 tl;dr

 While applying existing (and valid) migrations to a MySQL database, one of
 them failed with:
 {{{
 ValueError: The database backend does not accept 0 as a value for
 AutoField.
 }}}
 and after fixing the migration by hand, re-running `migrate` yields to
 this error:
 {{{
 MySQLdb.OperationalError: (1050, "Table 'testapp_modelz' already exists")
 }}}

 I'm reporting this as a bug because it's unclear to the user how they
 should proceed in this case. If the ticket is found invalid (likely), then
 perhaps we could consider adding to the error message an extra note on
 further steps?

 My naïve hope, as a user, was that after fixing the migration, a second
 run of `migrate` would succeed.

 Longer description:

 I have Django test project with some test apps in it. I usually switch the
 database settings to either use sqlite or Postgresql. Recently, I wanted
 to debug a issue using a MySQL database, so I started one using docker and
 I ensured I had a valid connection:

 {{{
 $ python -Wall manage.py dbshell
 Welcome to the MySQL monitor.  Commands end with ; or \g.
 Your MySQL connection id is 14
 Server version: 8.0.33 MySQL Community Server - GPL
 ...
 mysql>
 }}}

 Then, I made sure I had no pending migrations to generate, and immediately
 after I applied all the migrations:

 {{{
 $ python -Wall manage.py makemigrations
 No changes detected

 $ python -Wall manage.py migrate
 Operations to perform:
   Apply all migrations: admin, auth, contenttypes, sessions, testapp,
 ticket_30382
 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 sessions.0001_initial... OK
   Applying testapp.0001_initial... OK
   Applying
 testapp.0002_remove_grandchild_age_alter_child_parent_and_more... OK
   Applying testapp.0003_alter_article_authors... OK
   Applying testapp.0004_question_voter_choice... OK
   Applying
 testapp.0005_product_remove_choice_voters_images_delete_voter... OK
   Applying testapp.0006_modela_modelb... OK
   Applying testapp.0007_modelb_foo... OK
   Applying testapp.0008_rename_foo_modelb__foo... OK
   Applying
 testapp.0009_modelz_remove_modelb_id_modelb_modelz_ptr...Traceback (most
 recent call last):
   File "/home/nessita/fellowship/projectfromrepo/manage.py", line 22, in
 <module>
     main()
   File "/home/nessita/fellowship/projectfromrepo/manage.py", line 18, in
 main
     execute_from_command_line(sys.argv)
   File
 "/home/nessita/fellowship/django/django/core/management/__init__.py", line
 442, in execute_from_command_line
     utility.execute()
   File
 "/home/nessita/fellowship/django/django/core/management/__init__.py", line
 436, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/home/nessita/fellowship/django/django/core/management/base.py",
 line 412, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/home/nessita/fellowship/django/django/core/management/base.py",
 line 458, in execute
     output = self.handle(*args, **options)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/core/management/base.py",
 line 106, in wrapper
     res = handle_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/core/management/commands/migrate.py",
 line 356, in handle
     post_migrate_state = executor.migrate(
                          ^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/migrations/executor.py",
 line 135, in migrate
     state = self._migrate_all_forwards(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/migrations/executor.py",
 line 167, in _migrate_all_forwards
     state = self.apply_migration(
             ^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/migrations/executor.py",
 line 252, in apply_migration
     state = migration.apply(state, schema_editor)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/migrations/migration.py", line
 132, in apply
     operation.database_forwards(
   File
 "/home/nessita/fellowship/django/django/db/migrations/operations/fields.py",
 line 108, in database_forwards
     schema_editor.add_field(
   File
 "/home/nessita/fellowship/django/django/db/backends/mysql/schema.py", line
 107, in add_field
     super().add_field(model, field)
   File
 "/home/nessita/fellowship/django/django/db/backends/base/schema.py", line
 668, in add_field
     definition, params = self.column_sql(model, field,
 include_default=True)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/backends/base/schema.py", line
 359, in column_sql
     " ".join(
   File
 "/home/nessita/fellowship/django/django/db/backends/base/schema.py", line
 310, in _iter_column_sql
     default_value = self.effective_default(field)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/backends/base/schema.py", line
 429, in effective_default
     return field.get_db_prep_save(self._effective_default(field),
 self.connection)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/models/fields/related.py", line
 1149, in get_db_prep_save
     return self.target_field.get_db_prep_save(value,
 connection=connection)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/models/fields/__init__.py",
 line 957, in get_db_prep_save
     return self.get_db_prep_value(value, connection=connection,
 prepared=False)
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/models/fields/__init__.py",
 line 2748, in get_db_prep_value
     value = connection.ops.validate_autopk_value(value)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/backends/mysql/operations.py",
 line 250, in validate_autopk_value
     raise ValueError(
 ValueError: The database backend does not accept 0 as a value for
 AutoField.
 }}}

 I edited the troubling migration by hand, changing the default from `0` to
 `1`, but `migrate` would no longer work:
 {{{
 $ python -Wall manage.py migrate
 Operations to perform:
   Apply all migrations: admin, auth, contenttypes, sessions, testapp,
 ticket_30382
 Running migrations:
   Applying
 testapp.0009_modelz_remove_modelb_id_modelb_modelz_ptr...Traceback (most
 recent call last):
   File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
 87, in _execute
     return self.cursor.execute(sql)
            ^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/backends/mysql/base.py",
 line 75, in execute
     return self.cursor.execute(query, args)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
 packages/MySQLdb/cursors.py", line 206, in execute
     res = self._query(query)
           ^^^^^^^^^^^^^^^^^^
   File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
 packages/MySQLdb/cursors.py", line 319, in _query
     db.query(q)
   File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
 packages/MySQLdb/connections.py", line 254, in query
     _mysql.connection.query(self, query)
 MySQLdb.OperationalError: (1050, "Table 'testapp_modelz' already exists")

 The above exception was the direct cause of the following exception:

 Traceback (most recent call last):
   File "/home/nessita/fellowship/projectfromrepo/manage.py", line 22, in
 <module>
     main()
   File "/home/nessita/fellowship/projectfromrepo/manage.py", line 18, in
 main
     execute_from_command_line(sys.argv)
   File
 "/home/nessita/fellowship/django/django/core/management/__init__.py", line
 442, in execute_from_command_line
     utility.execute()
   File
 "/home/nessita/fellowship/django/django/core/management/__init__.py", line
 436, in execute
     self.fetch_command(subcommand).run_from_argv(self.argv)
   File "/home/nessita/fellowship/django/django/core/management/base.py",
 line 412, in run_from_argv
     self.execute(*args, **cmd_options)
   File "/home/nessita/fellowship/django/django/core/management/base.py",
 line 458, in execute
     output = self.handle(*args, **options)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/core/management/base.py",
 line 106, in wrapper
     res = handle_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/core/management/commands/migrate.py",
 line 356, in handle
     post_migrate_state = executor.migrate(
                          ^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/migrations/executor.py",
 line 135, in migrate
     state = self._migrate_all_forwards(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/migrations/executor.py",
 line 167, in _migrate_all_forwards
     state = self.apply_migration(
             ^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/migrations/executor.py",
 line 252, in apply_migration
     state = migration.apply(state, schema_editor)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File
 "/home/nessita/fellowship/django/django/db/migrations/migration.py", line
 132, in apply
     operation.database_forwards(
   File
 "/home/nessita/fellowship/django/django/db/migrations/operations/models.py",
 line 96, in database_forwards
     schema_editor.create_model(model)
   File
 "/home/nessita/fellowship/django/django/db/backends/base/schema.py", line
 451, in create_model
     self.execute(sql, params or None)
   File
 "/home/nessita/fellowship/django/django/db/backends/base/schema.py", line
 201, in execute
     cursor.execute(sql, params)
   File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
 102, in execute
     return super().execute(sql, params)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
 67, in execute
     return self._execute_with_wrappers(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
 80, in _execute_with_wrappers
     return executor(sql, params, many, context)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
 84, in _execute
     with self.db.wrap_database_errors:
   File "/home/nessita/fellowship/django/django/db/utils.py", line 91, in
 __exit__
     raise dj_exc_value.with_traceback(traceback) from exc_value
   File "/home/nessita/fellowship/django/django/db/backends/utils.py", line
 87, in _execute
     return self.cursor.execute(sql)
            ^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/fellowship/django/django/db/backends/mysql/base.py",
 line 75, in execute
     return self.cursor.execute(query, args)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
 packages/MySQLdb/cursors.py", line 206, in execute
     res = self._query(query)
           ^^^^^^^^^^^^^^^^^^
   File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
 packages/MySQLdb/cursors.py", line 319, in _query
     db.query(q)
   File "/home/nessita/.virtualenvs/djangodev/lib/python3.11/site-
 packages/MySQLdb/connections.py", line 254, in query
     _mysql.connection.query(self, query)
 django.db.utils.OperationalError: (1050, "Table 'testapp_modelz' already
 exists")
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34546>
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/01070187fc56ea1b-98239af3-f878-48c1-8f4f-b0dfd100b94c-000000%40eu-central-1.amazonses.com.

Reply via email to