Django 1.7 中的 Django-migrations 检测模型更改,但不会在迁移时应用它们

Posted

技术标签:

【中文标题】Django 1.7 中的 Django-migrations 检测模型更改,但不会在迁移时应用它们【英文标题】:Django-migrations in Django 1.7 detects model changes but does not apply them on migrate 【发布时间】:2014-12-24 12:21:14 【问题描述】:

我一直在尝试使用 1.7 中的迁移来同步对 Django 应用程序中模型的更改(postgres 9.1 - 如果您需要有关我的环境的更多详细信息,请告诉我),但 manage.py migrate 似乎没有做任何事情,并且 sqlmigrate 不会发出任何 SQL。

我认为Django 1.7 - "No migrations to apply" when run migrate after makemigrations 可能适用于我的情况,并且我确实在我的数据库的 django_migrations 表中找到了一些历史记录。我删除了我要迁移的应用的记录。

最近我放弃了让alter table statements 生成/运行并删除了表的原始版本。虽然 manage.py migrate 声明它正在应用迁移,但数据库没有任何反应。

以下是我一直在尝试的步骤:

删除历史记录。

rm -r myapp/migrations
../manage.py dbshell
myapp_db=> delete from django_migrations where app='myapp'

创建初始迁移。

cp myapp/models.py.orig myapp/models.py
../manage.py makemigrations myapp
../manage.py migrate

manage.py migrate 返回以下内容:

....
Running migrations:
  Applying myapp.0001_initial... FAKED

然后我换入新模型并生成新迁移。

cp myapp/models.py.new myapp/models.py
../manage.py makemigrations myapp

makemigrations 的结果在 myapp/migrations/0002_notificationlog.py:

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations


class Migration(migrations.Migration):

    dependencies = [
        ('myapp', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='NotificationLog',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('tstamp', models.DateTimeField(help_text=b'Log time', auto_now_add=True)),
                ('recipient', models.CharField(max_length=100)),
                ('subject', models.TextField()),
            ],
            options=
            ,
            bases=(models.Model,),
        ),
    ]

运行此迁移:

../manage.py migrate

manage.py migrate 就像一切正常:

....
Running migrations:
  Applying myapp.0002_notificationlog... OK

我可以看到日志条目出现在 django_migrations 中,但没有创建表。

我迷路了。知道接下来要尝试什么吗?

更新

按要求运行 migrate -v 3 时,我看到了

Running pre-migrate handlers for application auth

对于每个已安装的应用,后跟一条类似的行。

然后

Loading 'initial_data' fixtures...
Checking '/var/www/environment/default/myproj/myproj' for fixtures...
No fixture 'initial_data' in '/var/www/environment/default/myproj/myproj'.

共重复 13 次,非托管应用的数量。

然后

Running migrations:
  Applying myapp.0001_initial... FAKED

紧随其后

Running post-migrate handlers for application auth

每个已安装的应用都有类似的行。

对于迁移0002,输出是一样的,除了

Running migrations:
  Applying myapp.0002_notificationlog... OK

另请注意,sqlmigrate 也不输出任何内容:

../manage.py sqlmigrate myapp 0002 -v 3

什么都不生产。

更新 2

我将 myapp 复制到一个新项目中,并且能够在其上运行迁移,但是当我导入我的主项目设置时,迁移停止工作。是否有我应该注意的设置可能会影响迁移执行,特别是如果我一直在使用 South 和以前版本的 Django?

【问题讨论】:

所有这些步骤最初都是在 Django 1.7 上执行的,然后在 1.7.1 上重新测试。 再次运行该过程,但使用./manage.py migrate -v 3。那应该打印出额外的信息。请在您的问题中包含该信息。 我更新了结果,但输出效果不佳。我想我要创建一个具有相同模型的新项目,看看它是否与我的环境有关。 是否可以删除 .pyc 文件? 【参考方案1】:

问题在通用项目设置中消失了,而在我旧的、复杂的项目设置中又出现了。我将问题追溯到缺少allow_migrate 方法的数据库路由器类。

DATABASE_ROUTERS = [ 'myproj.routers.DatabaseAppsRouter', ]

我使用这个路由器来处理项目中单独应用程序的查询(只读/mysql)。

很遗憾,除了我自己,我不能责怪任何人,因为Django documentation 明确指出:

请注意,迁移不会对 [allow_migrate] 返回 False 的模型执行任何操作。 (link)

我前段时间创建了这个路由器,当我升级到 Django 1.7 时,没有将allow_migrate 方法添加到我的路由器类中。当我添加该方法并确保它在需要时返回 True 时,迁移运行并解决了问题。

【讨论】:

不能再上船了

以上是关于Django 1.7 中的 Django-migrations 检测模型更改,但不会在迁移时应用它们的主要内容,如果未能解决你的问题,请参考以下文章

Django 1.7 中的迁移

text 使用django 1.7中的迁移重命名字段

在迁移中获取模型 ContentType - Django 1.7

django admin 1.7 + django-grappelli 2.6.1 中的 jQuery datepicker 本地化

如何取消应用 django 1.7 中的第一次迁移 [重复]

在 Django 1.7 迁移中调用 loaddata 会抛出“‘字段列表’中的未知列‘[字段]’”