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

时间:2021-10-07 18:04:13

I'm running Django 1.6.6 on production and have recently upgraded to 1.9.7 on staging (dev server). This update was performed on the server and I followed the steps outlined here Upgrading from South.

我正在生产Django 1.6.6并且最近在登台(dev服务器)上升级到了1.9.7。此更新是在服务器上执行的,我按照此处概述的步骤从South升级。

I noticed that the structure of the migration files have changed, and they no longer include a create statement. This causes issues because if I pull this new code from my GitHub repo and run python manage.py makemigrations or python manage.py migrate, it says:

我注意到迁移文件的结构已更改,并且它们不再包含create语句。这会导致问题,因为如果我从我的GitHub仓库中提取这个新代码并运行python manage.py makemigrations或python manage.py migrate,它会说:

django.db.utils.OperationalError: no such table: appname_modelname

django.db.utils.OperationalError:没有这样的表:appname_modelname

The traceback points to my urls.py because I'm referencing the model in a queryset:

回溯指向我的urls.py,因为我在查询集中引用了模型:

queryset=list(chain(models.modelname.objects.filter(booleanField=True).order_by(object), models.aDifferentModel.objects.all())),

Prior to the 1.9 upgrade, syncdb created the tables for me, but this isn't the case with migrate. I've also tried python manage.py migrate --run-syncdb but this gives the same error.

在1.9升级之前,syncdb为我创建了表,但迁移不是这种情况。我也尝试过python manage.py migrate --run-syncdb,但这会产生同样的错误。

However, if I copy the SQLite database from my production or staging environments to my local machine and run the command, it works (because the table is already in the database).

但是,如果我将SQLite数据库从我的生产或登台环境复制到我的本地计算机并运行该命令,它就可以工作(因为该表已经在数据库中)。

Do I have to manually create these tables (though I assume not) or am I doing something wrong?

我是否必须手动创建这些表(虽然我没假设)或者我做错了什么?

Edit: Added code snippets and tracebacks. Sorry for not doing this initially.

编辑:添加了代码段和回溯。很抱歉没有这样做。

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

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


4  

The problem is that your queryset is being evaluated when the urls.py loads. When you run makemigrations for a new project, this causes the error because the table has not been created yet.

问题是在urls.py加载时正在评估您的查询集。当您为新项目运行makemigrations时,这会导致错误,因为尚未创建表。

You can fix this by subclassing ListView and moving the queryset into get_queryset.

您可以通过继承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()))

Then change your url pattern to use your new view.

然后更改您的网址格式以使用新视图。

url(r'^academy/howtoapply/$',
    MyListView.as_view(),
    name='apply',
),

Django 1.9 runs some checks to validate your url patterns, which means that the url patterns are loaded before the makemigrations command runs. Django 1.8 does not have these checks, so you can get away with setting the queryset as you have done.

Django 1.9运行一些检查以验证您的url模式,这意味着在makemigrations命令运行之前加载了url模式。 Django 1.8没有这些检查,所以你可以像你一样设置查询集。

#1


4  

The problem is that your queryset is being evaluated when the urls.py loads. When you run makemigrations for a new project, this causes the error because the table has not been created yet.

问题是在urls.py加载时正在评估您的查询集。当您为新项目运行makemigrations时,这会导致错误,因为尚未创建表。

You can fix this by subclassing ListView and moving the queryset into get_queryset.

您可以通过继承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()))

Then change your url pattern to use your new view.

然后更改您的网址格式以使用新视图。

url(r'^academy/howtoapply/$',
    MyListView.as_view(),
    name='apply',
),

Django 1.9 runs some checks to validate your url patterns, which means that the url patterns are loaded before the makemigrations command runs. Django 1.8 does not have these checks, so you can get away with setting the queryset as you have done.

Django 1.9运行一些检查以验证您的url模式,这意味着在makemigrations命令运行之前加载了url模式。 Django 1.8没有这些检查,所以你可以像你一样设置查询集。