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

Django-migrations in Django 1.7 detects model changes but does not apply them on migrate

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

我认为django 1.7-"no migrations to apply"when run migrate after makemigrations可能适用于我的情况,我确实在数据库的django_migrations表中找到了一些历史记录。我删除了正在尝试迁移的应用程序的记录。

最近,我放弃了获取alter table语句来生成/运行,并删除了表的原始版本。当manage.py迁移状态为它正在应用迁移时,数据库不会发生任何变化。

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

删除历史记录。

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

创建初始迁移。

1
2
3
cp myapp/models.py.orig myapp/models.py
../manage.py makemigrations myapp
../manage.py migrate

manage.py migrate返回以下内容:

1
2
3
....
Running migrations:
  Applying myapp.0001_initial... FAKED

然后我交换新的模型并生成一个新的迁移。

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

makeMigrations的结果在myapp/migrations/0002_notificationLog.py中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# -*- 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,),
        ),
    ]

运行此迁移:

1
../manage.py migrate

manage.py migrate的行为就像一切正常:

1
2
3
....
Running migrations:
  Applying myapp.0002_notificationlog... OK

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

我迷路了。知道下一步该怎么做吗?

更新

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

1
Running pre-migrate handlers for application auth

之后是每个已安装应用程序的类似行。

然后

1
2
3
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次,非托管应用程序的数目。

然后

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

然后

1
Running post-migrate handlers for application auth

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

对于迁移0002,输出是相同的,除了

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

还要注意,sqlmigrate也不输出任何内容:

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

什么都不生产。

更新2

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


这个问题在一般的项目设置中消失了,在我以前复杂的项目设置中重新出现。我跟踪到了一个缺少allow_migrate方法的数据库路由器类。

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

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

遗憾的是,除了我自己,我不能责怪任何人,因为Django文档清楚地说明:

Note that migrations will just silently not perform any operations on a model for which [allow_migrate] returns False. (link)

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