django 2.1.4迁移失败,并显示“详细信息:关键列“ xxx”和“ yyy”属于不兼容的类型:整数和字符变化”

时间:2018-12-05 09:30:05

标签: django

我正在尝试将基于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

1 个答案:

答案 0 :(得分:0)

我通过手动编辑以前可以正常运行的迁移来解决此问题,从而一开始就消除了主键字段类型的更改。即我的初始迁移现在已经包含模型规范,该模型规范在后来的迁移中已更改。在以后的迁移中,我完全删除了编辑。