Django psycopg2.ProgrammingError关系不存在使用自定义模型管理

2024-05-15 21:37:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我不能用我当前的代码库从头开始迁移。

运行./manage.py makemigrations reports将给出以下回溯

Traceback (most recent call last):
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "reports_frozenschedule" does not exist
LINE 1: ..._file", "reports_frozenschedule"."abandoned" FROM "reports_f...
                                                             ^


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

Traceback (most recent call last):
  File "./manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
    utility.execute()
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/management/__init__.py", line 359, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/management/base.py", line 294, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/management/base.py", line 342, in execute
    self.check()
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/management/base.py", line 374, in check
    include_deployment_checks=include_deployment_checks,
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/management/base.py", line 361, in _run_checks
    return checks.run_checks(**kwargs)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/checks/registry.py", line 81, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/checks/urls.py", line 14, in check_url_config
    return check_resolver(resolver)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/core/checks/urls.py", line 24, in check_resolver
    for pattern in resolver.url_patterns:
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/urls/resolvers.py", line 313, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/urls/resolvers.py", line 306, in urlconf_module
    return import_module(self.urlconf_name)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/importlib/__init__.py", line 109, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 1129, in _exec
  File "<frozen importlib._bootstrap>", line 1471, in exec_module
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed
  File "/home/jwe/Documents/piesup2/piesup2/urls.py", line 9, in <module>
    from reports.api import viewsets
  File "/home/jwe/Documents/piesup2/reports/api/viewsets.py", line 77, in <module>
    class ActiveServerViewSet(ReadOnlyModelViewSet):
  File "/home/jwe/Documents/piesup2/reports/api/viewsets.py", line 78, in ActiveServerViewSet
    queryset = Server.active.all()
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/models/manager.py", line 160, in all
    return self.get_queryset()
  File "/home/jwe/Documents/piesup2/reports/models.py", line 550, in get_queryset
    fqdn__in=active_server_fqdns()
  File "/home/jwe/Documents/piesup2/reports/models.py", line 541, in active_server_fqdns
    f.deserialize.servers for f in FrozenSchedule.objects.active()
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/models/query.py", line 256, in __iter__
    self._fetch_all()
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/models/query.py", line 1087, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/models/query.py", line 54, in __iter__
    results = compiler.execute_sql()
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/models/sql/compiler.py", line 835, in execute_sql
    cursor.execute(sql, params)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/jwe/Documents/piesup2/venv/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "reports_frozenschedule" does not exist
LINE 1: ..._file", "reports_frozenschedule"."abandoned" FROM "reports_f...

在堆栈跟踪之后,当Djagno扫描我的网址.py文件,看起来像:

^{pr2}$

它到达from reports.api import viewsets,在这里导入以下内容:

viewsets.py

from reports.models import Server

...

class ActiveServerViewSet(ReadOnlyModelViewSet):
    queryset = Server.active.all()
    ...

它使其成为依赖于自定义模型管理器的Server.active.all(),如下所示:

models.py

class ActiveServerManager(models.Manager):
    def get_queryset(self):
        return super(ActiveServerManager, self).get_queryset().filter(
            fqdn__in=active_server_fqdns()
        )


class Server(models.Model):
    fqdn = models.CharField(....)
    ....
    objects = models.Manager()
    active = ActiveServerManager()

我的服务器模型管理器调用函数active_server_fqdns(),如下所示:

def active_server_fqdns():
    # Returns flat set of FQDN's associated with all currently active Schedules
    return {server.fqdn for servers in [
        f.deserialize.servers for f in FrozenSchedule.objects.active()
    ] for server in servers}

此函数调用冻结计划.objects.active()内部的理解,这是一切爆炸的地方

自定义查询集FrozenSchedule.objects.active()如下所示。

Django抱怨说the relation "reports_frozenschedule" does not exist

class FrozenScheduleQuerySet(models.QuerySet):

    def active(self):
        return self.filter(
            Q(start_date__lte=Now()), Q(end_date__gte=Now()) | Q(end_date=None)
        )

class FrozenSchedule(models.Model):
      ....
      objects = FrozenScheduleQuerySet.as_manager()

为什么我的模型管理器会导致我的数据库迁移失败?

似乎有某种种族状况正在发生网址.py导致在实际注册表之前对queryset求值。

使用修复更新

正如建议的那样,修复方法是去掉模块级查询。我把它移到DjangoRestFramework提供的get_queryset()方法中,比如:

class ActiveServerViewSet(ReadOnlyModelViewSet):
    serializer_class = serializers.LinkedServerSerializer
    ...

    def get_queryset(self):
        return Server.active.all()

因为它不再有queryset属性,所以我不得不在viewset中添加一个basename参数

router.register(r'active-servers', viewsets.ActiveServerViewSet, 'Server')


Tags: djangoinpyselfhomeexecutevenvlib
1条回答
网友
1楼 · 发布于 2024-05-15 21:37:08

这是由模块级代码与数据库交互造成的:

class ActiveServerViewSet(ReadOnlyModelViewSet):
    queryset = Server.active.all()

当您运行makemigrations时,该代码将在模块加载时运行,并且,正如您所安排的那样,当相应的数据库表尚不存在时,FrozenScheduleQuerySet将被计算(for f in FrozenSchedule.objects.active())。在

通常应避免让模块级代码(包括方法之外的类定义)执行数据库查询,因为此代码是在模块导入时执行的,而模块导入通常是在启动服务器或运行管理命令时执行的。在

{例如^ a1:

you should never execute queries at module level

相关问题 更多 >