Reputation: 1536
We use django 1.8 and migrations in our project and we run repeatedly into the following problem:
Now one of the developers sync the 3 new migrations and encounters an error due to the mismatch between models.py and the database.
So far we have either faked the migrations which errors out or we changed dependencies ad hoc. This is neither systematic nor convenient though.
Is there any better way to approach the problem?
Following is a simple example of how the problem arise: original models.py
class Test(models.Model):
a = models.CharField(max_length=200, verbose_name="A")
b = models.CharField(max_length=200, verbose_name="B")
migrations before model change:
0001_initial.py
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='Test',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('a', models.CharField(max_length=200, verbose_name=b'A')),
('b', models.CharField(max_length=200, verbose_name=b'B')),
],
),
]
0002_auto_20160308_1103.py
def testData(apps, schema_editor):
Test.objects.create(a="aaaa", b="bbb")
class Migration(migrations.Migration):
dependencies = [
('Test', '0001_initial'),
]
operations = [
migrations.RunPython(testData)
]
new models.py
class Test(models.Model):
a = models.CharField(max_length=200, verbose_name="A")
b = models.CharField(max_length=200, verbose_name="B")
c = models.CharField(max_length=200, verbose_name="C", default="c")
last migration:
0003_test_c.py
class Migration(migrations.Migration):
dependencies = [
('Test', '0002_auto_20160308_1103'),
]
operations = [
migrations.AddField(
model_name='test',
name='c',
field=models.CharField(default=b'c', max_length=200, verbose_name=b'C'),
),
]
running migrate
results in django.db.utils.OperationalError: table Test_test has no column named c
while running the second migration.
Upvotes: 1
Views: 796
Reputation: 599926
You are not using the functionality that the migrations system provides. In particular, you're referencing the Test model directly; but the migrations system includes the concept of "historical models" which are built up dynamically from the migrations up to that point, which therefore solves this problem precisely.
The documentation explains this further, but basically instead of importing Test in migration 0002, you should get it dynamically:
def testData(apps, schema_editor):
Test = apps.get_model("myapp", "Test")
Test.objects.create(a="aaaa", b="bbb")
Upvotes: 3