首页 > 解决方案 > 将 django 从 3.0.4 升级到 3.2.6 导致测试时缺少 content_type 对象

问题描述

我正在尝试将项目从 Django 3.0.4 迁移到 3.2.6。我在运行我的测试套件时遇到了以下问题

django.db.utils.IntegrityError: insert or update on table "auth_permission" violates foreign key constraint "auth_permission_content_type_id_2f476e4b_fk_django_co"
DETAIL:  Key (content_type_id)=(1) is not present in table "django_content_type".
self = <QuerySet []>, defaults = {'name': 'Can export log entry (adminactions)'}
kwargs = {'codename': 'adminactions_export_logentry', 'content_type': <ContentType: admin | log entry>}
params = {'codename': 'adminactions_export_logentry', 'content_type': <ContentType: admin | log entry>, 'name': 'Can export log entry (adminactions)'}

    def get_or_create(self, defaults=None, **kwargs):
        """
        Look up an object with the given kwargs, creating one if necessary.
        Return a tuple of (object, created), where created is a boolean
        specifying whether an object was created.
        """
        # The get() needs to be targeted at the write database in order
        # to avoid potential transaction consistency problems.
        self._for_write = True
        try:
>           return self.get(**kwargs), False

/usr/local/lib/python3.9/site-packages/django/db/models/query.py:581: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <QuerySet []>, args = ()
kwargs = {'codename': 'adminactions_export_logentry', 'content_type': <ContentType: admin | log entry>}
clone = <QuerySet []>, limit = 21, num = 0

    def get(self, *args, **kwargs):
        """
        Perform the query and return a single object matching the given
        keyword arguments.
        """
        if self.query.combinator and (args or kwargs):
            raise NotSupportedError(
                'Calling QuerySet.get(...) with filters after %s() is not '
                'supported.' % self.query.combinator
            )
        clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
        if self.query.can_filter() and not self.query.distinct_fields:
            clone = clone.order_by()
        limit = None
        if not clone.query.select_for_update or connections[clone.db].features.supports_select_for_update_with_limit:
            limit = MAX_GET_RESULTS
            clone.query.set_limits(high=limit)
        num = len(clone)
        if num == 1:
            return clone._result_cache[0]
        if not num:
>           raise self.model.DoesNotExist(
                "%s matching query does not exist." %
                self.model._meta.object_name
            )
E           django.contrib.auth.models.Permission.DoesNotExist: Permission matching query does not exist.

/usr/local/lib/python3.9/site-packages/django/db/models/query.py:435: DoesNotExist

During handling of the above exception, another exception occurred:

self = <django.contrib.gis.db.backends.postgis.base.DatabaseWrapper object at 0x7f5851e05790>

    def _commit(self):
        if self.connection is not None:
            with self.wrap_database_errors:
>               return self.connection.commit()
E               psycopg2.errors.ForeignKeyViolation: insert or update on table "auth_permission" violates foreign key constraint "auth_permission_content_type_id_2f476e4b_fk_django_co"
E               DETAIL:  Key (content_type_id)=(1) is not present in table "django_content_type".

/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py:242: ForeignKeyViolation

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

self = <tests.integration.myapp.test_xyz testMethod=test_xyz>
result = <TestCaseFunction test_xyz>, debug = False

    def _setup_and_call(self, result, debug=False):
        """
        Perform the following in order: pre-setup, run test, post-teardown,
        skipping pre/post hooks if test is set to be skipped.
    
        If debug=True, reraise any errors in setup and use super().debug()
        instead of __call__() to run the test.
        """
        testMethod = getattr(self, self._testMethodName)
        skipped = (
            getattr(self.__class__, "__unittest_skip__", False) or
            getattr(testMethod, "__unittest_skip__", False)
        )
    
        # Convert async test methods.
        if asyncio.iscoroutinefunction(testMethod):
            setattr(self, self._testMethodName, async_to_sync(testMethod))
    
        if not skipped:
            try:
                self._pre_setup()
            except Exception:
                if debug:
                    raise
                result.addError(self, sys.exc_info())
                return
        if debug:
            super().debug()
        else:
            super().__call__(result)
        if not skipped:
            try:
>               self._post_teardown()

/usr/local/lib/python3.9/site-packages/django/test/testcases.py:284: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python3.9/site-packages/django/test/testcases.py:1006: in _post_teardown
    self._fixture_teardown()
/usr/local/lib/python3.9/site-packages/django/test/testcases.py:1038: in _fixture_teardown
    call_command('flush', verbosity=0, interactive=False,
/usr/local/lib/python3.9/site-packages/django/core/management/__init__.py:181: in call_command
    return command.execute(*args, **defaults)
/usr/local/lib/python3.9/site-packages/django/core/management/base.py:398: in execute
    output = self.handle(*args, **options)
/usr/local/lib/python3.9/site-packages/django/core/management/commands/flush.py:80: in handle
    emit_post_migrate_signal(verbosity, interactive, database)
/usr/local/lib/python3.9/site-packages/django/core/management/sql.py:42: in emit_post_migrate_signal
    models.signals.post_migrate.send(
/usr/local/lib/python3.9/site-packages/django/dispatch/dispatcher.py:180: in send
    return [
/usr/local/lib/python3.9/site-packages/django/dispatch/dispatcher.py:181: in <listcomp>
    (receiver, receiver(signal=self, sender=sender, **named))
/usr/local/lib/python3.9/site-packages/adminactions/models.py:9: in create_extra_permissions_handler
    p.create_extra_permissions()
/usr/local/lib/python3.9/site-packages/adminactions/perms.py:37: in create_extra_permissions
    Permission.objects.get_or_create(**params)
/usr/local/lib/python3.9/site-packages/django/db/models/manager.py:85: in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
/usr/local/lib/python3.9/site-packages/django/db/models/query.py:588: in get_or_create
    return self.create(**params), True
/usr/local/lib/python3.9/site-packages/django/db/transaction.py:246: in __exit__
    connection.commit()
/usr/local/lib/python3.9/site-packages/django/utils/asyncio.py:26: in inner
    return func(*args, **kwargs)
/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py:266: in commit
    self._commit()
/usr/local/lib/python3.9/site-packages/django/db/backends/base/base.py:242: in _commit
    return self.connection.commit()
/usr/local/lib/python3.9/site-packages/django/db/utils.py:90: in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value

我正在使用最新版本的 pytest 和 pytest-django 运行测试。这是我的依赖项列表:

Django==3.2.6
psycopg2-binary==2.9.1
djangorestframework==3.11.0
wheel==0.37.0
setuptools==57.4.0
bcrypt==3.2.0
boto==2.49.0
django-import-export==2.5.0
django-admin-rangefilter==0.8.1
responses==0.13.4
django-redis==4.12.1
redis-py-cluster==2.1.0
redis==3.5.3
hiredis==1.1.0
pytest==6.2.4
pytest-django==4.4.0
pytest-xdist==2.3.0
pytest-cov==2.12.1
django-storages==1.9.1
factory-boy==2.12.0
djangorestframework-csv==2.1.0
pdfkit==0.6.1
datadog==0.42.0
fuzzywuzzy[speedup]==0.17.0
boto3==1.18.20
django-adminplus==0.5
django-ses==2.2.1
django-adminactions==1.13.1
paramiko==2.7.2
scp==0.13.6
django-silk==4.1.0
python-geohash==0.8.5
django-dbsettings==1.1.0
django-cors-headers==3.7.0
django-filter==2.4.0
django-json-widget==1.1.1
django-mathfilters==1.0.0

我已经阅读了更改日志,但我找不到任何关于此的内容。

标签: pythondjangopytestpytest-django

解决方案


推荐阅读