Chris
Chris

Reputation: 105

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

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?

Upvotes: 2

Views: 2511

Answers (1)

Chris
Chris

Reputation: 105

The problem disappeared with generic project settings and reappeared with my old, complex project settings. I tracked the problem down to a database Router class that was missing an allow_migrate method.

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

I use this router to handle queries for a separate app in the project (readonly/MySQL).

Sadly I can't blame anyone but myself, since the Django documentation states clearly:

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

I had created this router some time ago and didn't add the allow_migrate method to my router class when I upgraded to Django 1.7. When I added the method and made sure it returned True when needed, migrations run and the problem is solved.

Upvotes: 5

Related Questions