I have a model in Django which represents a MySQL table that has some extra columns. I want to add a field to the model for one of these extra columns but I’m not sure how best to do it.
Let’s say the person
table has an age
column. My model looks like:
class Person(models.Model):
name = models.CharField(min_length=200)
If I add an age field like:
age = models.IntegerField(db_column="age")
then when I migrate I get an error about “Duplicate column name ‘age'” because it tries to create it. Is there a way around this?
What I’ve tried:
-
Add the field with a new column and make a migration for that:
age = models.IntegerField(db_column="age_2")
-
Create a manual data migration to copy data from original column to new one:
UPDATE person SET age_2 = age;
-
Create a manual migration to drop the original column:
ALTER TABLE person DROP COLUMN age;
-
Create a manual migration to rename the new column:
ALTER TABLE person CHANGE COLUMN age_2 age INT(11) NOT NULL;
-
On the model change it to use the
age
column (db_column="age"
) and make an automatic migration.
This works on my existing database, but when I run my tests, and it applies all the migrations to create a test database, it complains about Unknown column 'age' in 'field list'
(with no indication which migration is causing this).
Traceback from trying to run tests:
Traceback (most recent call last):
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/utils.py", line 87, in _execute
return self.cursor.execute(sql)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/django/base.py", line 149, in execute
return self.cursor.execute(query, new_args)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/cursor.py", line 572, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/connection.py", line 922, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/connection.py", line 732, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1054 (42S22): Unknown column 'age' in 'field list'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 24, in <module>
main()
File "manage.py", line 20, in main
execute_from_command_line(sys.argv)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
utility.execute()
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/__init__.py", line 440, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/commands/test.py", line 24, in run_from_argv
super().run_from_argv(argv)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/base.py", line 414, in run_from_argv
self.execute(*args, **cmd_options)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/commands/test.py", line 68, in handle
failures = test_runner.run_tests(test_labels)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/test/runner.py", line 1000, in run_tests
old_config = self.setup_databases(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/test/runner.py", line 898, in setup_databases
return _setup_databases(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/test/utils.py", line 220, in setup_databases
connection.creation.create_test_db(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/base/creation.py", line 79, in create_test_db
call_command(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/__init__.py", line 198, in call_command
return command.execute(*args, **defaults)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/base.py", line 460, in execute
output = self.handle(*args, **options)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/base.py", line 98, in wrapped
res = handle_func(*args, **kwargs)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/core/management/commands/migrate.py", line 290, in handle
post_migrate_state = executor.migrate(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/migrations/executor.py", line 131, in migrate
state = self._migrate_all_forwards(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/migrations/executor.py", line 163, in _migrate_all_forwards
state = self.apply_migration(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/migrations/executor.py", line 248, in apply_migration
state = migration.apply(state, schema_editor)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/migrations/migration.py", line 131, in apply
operation.database_forwards(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/migrations/operations/special.py", line 106, in database_forwards
self._run_sql(schema_editor, self.sql)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/migrations/operations/special.py", line 129, in _run_sql
schema_editor.execute(sql, params=params)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/base/schema.py", line 192, in execute
cursor.execute(sql, params)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/utils.py", line 67, in execute
return self._execute_with_wrappers(
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/utils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/utils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/django/db/backends/utils.py", line 87, in _execute
return self.cursor.execute(sql)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/django/base.py", line 149, in execute
return self.cursor.execute(query, new_args)
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/cursor.py", line 572, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/connection.py", line 922, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "/root/.local/share/virtualenvs/code-_Py8Si6I/lib/python3.8/site-packages/mysql/connector/connection.py", line 732, in _handle_result
raise errors.get_exception(packet)
django.db.utils.ProgrammingError: (1054, "1054 (42S22): Unknown column 'age' in 'field list'", '42S22')