2

I have been trying to synchronize changes to a model in a Django app using migrations in 1.7 (postgres 9.1 - let me know if you need more details of my environment), but manage.py migrate doesn't seem to do anything, and sqlmigrate doesn't emit any SQL.

I thought Django 1.7 - "No migrations to apply" when run migrate after makemigrations might be applicable to my situation, and I did find some history in the django_migrations table in my database. I deleted the records for the app I am trying to migrate.

Recently I gave up on getting the alter table statements to generate/run and dropped the original version of the table. And while manage.py migrate states it is applying the migration, nothing happens to the database.

Here are the steps I've been trying:

Delete the history.

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

Create an initial migration.

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

manage.py migrate returns the following:

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

Then I swap in the new models and generate a new migration.

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

The result of makemigrations is in 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,),
        ),
    ]

Run this migration:

../manage.py migrate

manage.py migrate acts like everything is OK:

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

I can see the log entries appear in django_migrations, but the table is not created.

I'm lost. Any idea what to try next?

Update

When running migrate -v 3 as requested, I see

Running pre-migrate handlers for application auth

followed by a similar line for each installed app.

Then

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

repeated a total of 13 times, the number of unmanaged apps.

Then

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

followed by

Running post-migrate handlers for application auth

with a similar line for each installed app.

For migration 0002, the output is the same, except for

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

Note also that sqlmigrate doesn't output anything either:

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

Produces nothing at all.

Update 2

I copied myapp into a new project and was able to run migrations on it, but migrations stopped working when I imported my main project settings. Are there settings I should be aware of that could affect migration execution, particularly if I've been using South with previous versions of Django?

4

1 回答 1

5

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

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

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

可悲的是,除了我自己,我不能责怪任何人,因为Django 文档明确指出:

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

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

于 2014-10-30T00:06:39.527 回答