我正在尝试将基于django 1.11的服务升级到最新的django 2.1.4。 在运行迁移时(在单元测试期间),我现在在django应用程序的现有迁移中遇到以下错误,该错误在升级到最新django版本之前没有发生!?
DETAIL: Key columns "xxx" and "yyy" are of incompatible types: integer and character varying
。
在升级到最新的django版本时如何解决现有的django迁移?
模型(摘要)从
class Aaa(models.model):
# id based on default primary key => integer based
class Bbb(models.model):
# id based on default primary key => integer based
aaa = models.ForeignKey(Aaa, on_delete=models.CASCADE)
到
class Aaa(models.model):
id = models.CharField(primary_key=True, max_length=36, editable=False)
class Bbb(models.model):
id = models.CharField(primary_key=True, max_length=36, editable=False)
aaa = models.ForeignKey(Aaa, on_delete=models.CASCADE)
在设置单元测试环境时(从头开始)迁移期间异常的调用栈如下所示:
foo_aaa__________ ERROR at setup of ViewTests.test_aaa ___________
self = <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>
sql = 'ALTER TABLE "foo_aaa" ALTER COLUMN "id" TYPE varchar(36) USING "id"::varchar(36)'
params = []
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fa7b5235780>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>})
def _execute(self, sql, params, *ignored_wrapper_args):
self.db.validate_no_broken_transaction()
with self.db.wrap_database_errors:
if params is None:
return self.cursor.execute(sql)
else:
> return self.cursor.execute(sql, params)
E psycopg2.ProgrammingError: foreign key constraint "foo_bbb_aaa_id_1e82a2eb_fk_foo" cannot be implemented
E DETAIL: Key columns "aaa_id" and "id" are of incompatible types: integer and character varying.
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:85: ProgrammingError
The above exception was the direct cause of the following exception:
request = <SubRequest '_django_setup_unittest' for <TestCaseFunction 'test_aaa'>>
django_db_blocker = <pytest_django.plugin._DatabaseBlocker object at 0x7fa7b83b9ba8>
@pytest.fixture(autouse=True, scope="class")
def _django_setup_unittest(request, django_db_blocker):
"""Setup a django unittest, internal to pytest-django."""
if django_settings_is_configured() and is_django_unittest(request):
request.getfixturevalue("django_test_environment")
> request.getfixturevalue("django_db_setup")
/usr/local/lib/python3.6/site-packages/pytest_django/plugin.py:486:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.6/site-packages/six.py:692: in reraise
raise value.with_traceback(tb)
/usr/local/lib/python3.6/site-packages/pytest_django/fixtures.py:110: in django_db_setup
**setup_databases_args
/usr/local/lib/python3.6/site-packages/django/test/utils.py:174: in setup_databases
serialize=connection.settings_dict.get('TEST', {}).get('SERIALIZE', True),
/usr/local/lib/python3.6/site-packages/django/db/backends/base/creation.py:68: in create_test_db
run_syncdb=True,
/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py:148: in call_command
return command.execute(*args, **defaults)
/usr/local/lib/python3.6/site-packages/django/core/management/base.py:353: in execute
output = self.handle(*args, **options)
/usr/local/lib/python3.6/site-packages/django/core/management/base.py:83: in wrapped
res = handle_func(*args, **kwargs)
/usr/local/lib/python3.6/site-packages/django/core/management/commands/migrate.py:203: in handle
fake_initial=fake_initial,
/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py:117: in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py:147: in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py:244: in apply_migration
state = migration.apply(state, schema_editor)
/usr/local/lib/python3.6/site-packages/django/db/migrations/migration.py:124: in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
/usr/local/lib/python3.6/site-packages/django/db/migrations/operations/fields.py:216: in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py:523: in alter_field
old_db_params, new_db_params, strict)
/usr/local/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py:122: in _alter_field
new_db_params, strict,
/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py:663: in _alter_field
params,
/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py:133: in execute
cursor.execute(sql, params)
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:68: in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:77: in _execute_with_wrappers
return executor(sql, params, many, context)
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:85: in _execute
return self.cursor.execute(sql, params)
/usr/local/lib/python3.6/site-packages/django/db/utils.py:89: in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>
sql = 'ALTER TABLE "foo_aaa" ALTER COLUMN "id" TYPE varchar(36) USING "id"::varchar(36)'
params = []
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fa7b5235780>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>})
def _execute(self, sql, params, *ignored_wrapper_args):
self.db.validate_no_broken_transaction()
with self.db.wrap_database_errors:
if params is None:
return self.cursor.execute(sql)
else:
> return self.cursor.execute(sql, params)
E django.db.utils.ProgrammingError: foreign key constraint "foo_bbb_aaa_id_1e82a2eb_fk_foo" cannot be implemented
E DETAIL: Key columns "aaa_id" and "id" are of incompatible types: integer and character varying.
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:85: ProgrammingError
_____ ERROR at setup of ViewTests.test_bar ______
self = <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>
sql = 'ALTER TABLE "foo_aaa" ALTER COLUMN "id" TYPE varchar(36) USING "id"::varchar(36)'
params = []
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fa7b5235780>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>})
def _execute(self, sql, params, *ignored_wrapper_args):
self.db.validate_no_broken_transaction()
with self.db.wrap_database_errors:
if params is None:
return self.cursor.execute(sql)
else:
> return self.cursor.execute(sql, params)
E psycopg2.ProgrammingError: foreign key constraint "foo_bbb_aaa_id_1e82a2eb_fk_foo" cannot be implemented
E DETAIL: Key columns "aaa_id" and "id" are of incompatible types: integer and character varying.
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:85: ProgrammingError
The above exception was the direct cause of the following exception:
tp = <class 'django.db.utils.ProgrammingError'>, value = None, tb = None
def reraise(tp, value, tb=None):
try:
if value is None:
value = tp()
if value.__traceback__ is not tb:
> raise value.with_traceback(tb)
/usr/local/lib/python3.6/site-packages/six.py:692:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/local/lib/python3.6/site-packages/pytest_django/plugin.py:486: in _django_setup_unittest
request.getfixturevalue("django_db_setup")
/usr/local/lib/python3.6/site-packages/six.py:692: in reraise
raise value.with_traceback(tb)
/usr/local/lib/python3.6/site-packages/pytest_django/fixtures.py:110: in django_db_setup
**setup_databases_args
/usr/local/lib/python3.6/site-packages/django/test/utils.py:174: in setup_databases
serialize=connection.settings_dict.get('TEST', {}).get('SERIALIZE', True),
/usr/local/lib/python3.6/site-packages/django/db/backends/base/creation.py:68: in create_test_db
run_syncdb=True,
/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py:148: in call_command
return command.execute(*args, **defaults)
/usr/local/lib/python3.6/site-packages/django/core/management/base.py:353: in execute
output = self.handle(*args, **options)
/usr/local/lib/python3.6/site-packages/django/core/management/base.py:83: in wrapped
res = handle_func(*args, **kwargs)
/usr/local/lib/python3.6/site-packages/django/core/management/commands/migrate.py:203: in handle
fake_initial=fake_initial,
/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py:117: in migrate
state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py:147: in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
/usr/local/lib/python3.6/site-packages/django/db/migrations/executor.py:244: in apply_migration
state = migration.apply(state, schema_editor)
/usr/local/lib/python3.6/site-packages/django/db/migrations/migration.py:124: in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
/usr/local/lib/python3.6/site-packages/django/db/migrations/operations/fields.py:216: in database_forwards
schema_editor.alter_field(from_model, from_field, to_field)
/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py:523: in alter_field
old_db_params, new_db_params, strict)
/usr/local/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py:122: in _alter_field
new_db_params, strict,
/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py:663: in _alter_field
params,
/usr/local/lib/python3.6/site-packages/django/db/backends/base/schema.py:133: in execute
cursor.execute(sql, params)
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:68: in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:77: in _execute_with_wrappers
return executor(sql, params, many, context)
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:85: in _execute
return self.cursor.execute(sql, params)
/usr/local/lib/python3.6/site-packages/django/db/utils.py:89: in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>
sql = 'ALTER TABLE "foo_aaa" ALTER COLUMN "id" TYPE varchar(36) USING "id"::varchar(36)'
params = []
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fa7b5235780>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7fa7ac64a240>})
def _execute(self, sql, params, *ignored_wrapper_args):
self.db.validate_no_broken_transaction()
with self.db.wrap_database_errors:
if params is None:
return self.cursor.execute(sql)
else:
> return self.cursor.execute(sql, params)
E django.db.utils.ProgrammingError: foreign key constraint "foo_bbb_aaa_id_1e82a2eb_fk_foo" cannot be implemented
E DETAIL: Key columns "aaa_id" and "id" are of incompatible types: integer and character varying.
/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:85: ProgrammingError
答案 0 :(得分:0)
我通过手动编辑以前可以正常运行的迁移来解决此问题,从而一开始就消除了主键字段类型的更改。即我的初始迁移现在已经包含模型规范,该模型规范在后来的迁移中已更改。在以后的迁移中,我完全删除了编辑。