【发布时间】:2017-01-19 13:08:59
【问题描述】:
我无法使用我当前的代码库从头开始进行任何迁移。
运行 ./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 扫描我的 urls.py 文件时,中断开始,如下所示:
from django.conf.urls import include, url
from rest_framework import routers
from reports.api import viewsets
router = routers.DefaultRouter()
router.register(r'active-servers', viewsets.ActiveServerViewSet)
...
urlpatterns = [
url(r'^api/', include(router.urls)),
url(r'^', include('reports.urls')),
]
它到达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}
这个函数在集合理解中调用 FrozenSchedule.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()
为什么我的模型管理器会导致我的数据库迁移失败?
似乎 urls.py 发生了某种竞争条件,导致查询集在表实际注册之前被评估。
更新修复
修复是,如建议摆脱模块级查询。我已经把它移到了 DjangoRestFramework 提供的 get_queryset() 方法中,比如:
class ActiveServerViewSet(ReadOnlyModelViewSet):
serializer_class = serializers.LinkedServerSerializer
...
def get_queryset(self):
return Server.active.all()
由于它不再具有查询集属性,我不得不向我的视图集添加一个 base_name 参数
router.register(r'active-servers', viewsets.ActiveServerViewSet, 'Server')
【问题讨论】: