从Django 1.6升级到1.9:python manage.py迁移失败

7
我正在生产环境中使用Django 1.6.6,最近在开发服务器上升级到了1.9.7。此次更新是在服务器上执行的,我按照这里从South升级概述的步骤进行了操作。
我注意到迁移文件的结构已经改变,它们不再包含create语句。这会导致问题,因为如果我从GitHub库中拉取这个新代码并运行python manage.py makemigrationspython manage.py migrate,它会显示: django.db.utils.OperationalError: no such table: appname_modelname 跟踪回溯到我的urls.py,因为我在queryset中引用了模型: queryset=list(chain(models.modelname.objects.filter(booleanField=True).order_by(object), models.aDifferentModel.objects.all())), 在1.9升级之前,syncdb会为我创建表格,但migrate不会这样做。我也尝试过python manage.py migrate --run-syncdb,但是仍然出现相同的错误。
然而,如果我将SQLite数据库从生产或者staging环境复制到本地机器并运行命令,它可以正常工作(因为表已经在数据库中)。 我是否需要手动创建这些表(尽管我认为不需要)或者我做错了什么? 编辑:添加了代码片段和跟踪。对于一开始没有做到这一点,我很抱歉。

models.py

class HowToApply(models.Model):
    title = models.CharField(max_length=500, blank=True, null=True)
    notice = models.TextField(blank=True, null=True)
description = models.TextField(blank=True, null=True)
active = models.BooleanField(default=None)
image = models.FileField(upload_to='numeric/img/%Y', blank=True, null=True)
mobile_image = models.FileField(upload_to='mobile/img/%Y', blank=True, null=True)
sequence_number = models.IntegerField(unique=True)

...

urls.py

from django.conf.urls import patterns, include, url
from django.views.generic import RedirectView, TemplateView, ListView, CreateView
from numeric import models, forms, views
from honeypot.decorators import check_honeypot
from numeric.views import CheckDeviceView
from itertools import chain

urlpatterns = patterns('',
    url(r'^academy/howtoapply/$',
        ListView.as_view(
            queryset =  list(chain(models.HowToApply.objects.filter(active=True).order_by('sequence_number'), models.AcademyAdmin.objects.all())),
        template_name = 'numeric/apply.html'
    ),
    name='apply'),

...

回溯

Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line
    utility.execute()
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 342, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 348, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 398, in execute
    self.check()
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 426, in check
    include_deployment_checks=include_deployment_checks,
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/checks/registry.py", line 75, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 10, in check_url_config
    return check_resolver(resolver)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/checks/urls.py", line 19, in check_resolver
    for pattern in resolver.url_patterns:
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 417, in url_patterns
    patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 33, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/core/urlresolvers.py", line 410, in urlconf_module
    return import_module(self.urlconf_name)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/var/www/website_mig/project/urls.py", line 14, in <module>
    (r'^', include('numeric.urls')),
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/conf/urls/__init__.py", line 52, in include
    urlconf_module = import_module(urlconf_module)
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
  File "/var/www/website_mig/numeric/urls.py", line 144, in <module>
    queryset = list(chain(models.HowToApply.objects.filter(active=True).order_by('sequence_number'), models.AcademyAdmin.objects.all())),
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 258, in __iter__
    self._fetch_all()
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 1074, in _fetch_all
    self._result_cache = list(self.iterator())
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/models/query.py", line 52, in __iter__
    results = compiler.execute_sql()
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 852, in execute_sql
    cursor.execute(sql, params)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/utils.py", line 95, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/var/www/website_mig/venv/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: numeric_howtoapply`

1
升级到1.9之前,您应该先逐步升级(先升级到1.7,然后再升级到1.8)。这样会使升级变得更加容易。 - Sayse
@SvenMarnach 我不知道。当我使用 syncdb 时这种情况不会发生。 - Keenan Lawrence
@DeepSpace,是的,我有。同样的错误。 - Keenan Lawrence
我理解urls.py中的查询在导入时执行(因为通常该文件中的所有代码都在导入时执行)。如果这是真的,您可以通过检查回溯来轻松地看到为什么会导入urls.py。更一般地说,我认为我们需要更多信息才能帮助您(您代码的相关部分以及您获得的完整回溯)。 - Sven Marnach
@KeenanLawrence 从回溯中可以看出,Django正在导入URL模式作为检查的一部分。我不知道它在做什么(显然自1.9版本以来才这样)。无论如何,发布实际代码和回溯有助于获得答案(这几乎总是如此)。 - Sven Marnach
显示剩余8条评论
1个回答

8
问题在于当 urls.py 加载时,您的查询集正在被评估。当您为新项目运行 makemigrations 时,这会导致错误,因为尚未创建表格。
您可以通过子类化 ListView 并将查询集移动到 get_queryset 中来解决此问题。
class MyListView(ListView):
    template_name = 'numeric/apply.html'

    def get_queryset(self):
        return list(chain(models.HowToApply.objects.filter(active=True).order_by('sequence_number'), models.AcademyAdmin.objects.all()))

然后将您的url模式更改为使用您的新视图。
url(r'^academy/howtoapply/$',
    MyListView.as_view(),
    name='apply',
),

Django 1.9在验证您的URL模式之前运行一些检查,这意味着URL模式在makemigrations命令运行之前已经被加载。Django 1.8没有这些检查,因此您可以像您现在所做的那样设置查询集而不会遇到问题。


这个解决方案非常完美!非常感谢你! - Keenan Lawrence
2
我以稍微不同的方式遇到了相同的问题。检查loads urls.py,然后加载views.py,然后加载forms.py,然后其中一个表单具有ModelChoiceField,因为queryset参数而导致异常。有没有办法解决这个问题?在Django 1.9中,ModelChioceFields queryset是否应该以不同的方式处理? - thelinuxer
据我所知,ModelChoiceFields不应该引起问题。我建议您提出一个新问题,并包含代码和回溯信息。 - Alasdair
1
我发现我的问题与ModelChoiceField的初始属性有关。将其移动到表单的__init__中,现在一切都正常工作了。 - thelinuxer
很高兴能帮助到你 :) - thelinuxer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接