Django数据迁移与models.py不匹配

时间:2016-03-08 10:03:07

标签: python django django-migrations

我们在项目中使用django 1.8和迁移,并且我们反复运行以下问题:

  1. 我们使用迁移1
  2. 更改/添加模型
  3. 我们添加/更改一些数据以满足迁移2的新逻辑
  4. 我们再次更改模型并创建迁移3
  5. 现在,其中一个开发人员同步了3个新的迁移,并且由于models.py和数据库之间的不匹配而遇到错误。

    到目前为止,我们要么伪造出错误的迁移,要么我们特意改变了依赖关系。尽管如此,这既不系统也不方便。

    有没有更好的方法来解决这个问题?

    以下是问题出现的简单示例: 原始models.py

    class Test(models.Model):
        a = models.CharField(max_length=200, verbose_name="A")
        b = models.CharField(max_length=200, verbose_name="B")
    
    模型更改前的

    迁移:

    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")
    

    上次迁移:

    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'),
            ),
        ]
    

    运行migrate会在运行第二次迁移时产生django.db.utils.OperationalError: table Test_test has no column named c

1 个答案:

答案 0 :(得分:3)

您没有使用迁移系统提供的功能。特别是,您可以直接引用测试模型;但迁移系统包括"历史模型"这是从迁移到动点建立的,因此可以精确地解决这个问题。

documentation进一步解释了这一点,但基本上不是在迁移0002中导入Test,而是应该动态地获取它:

def testData(apps, schema_editor):
    Test = apps.get_model("myapp", "Test")
    Test.objects.create(a="aaaa", b="bbb")