【问题标题】:Django data migration mismatch with models.pyDjango 数据迁移与 models.py 不匹配
【发布时间】:2016-06-22 05:12:54
【问题描述】:

我们在项目中使用 django 1.8 和迁移,我们反复遇到以下问题:

  1. 我们通过迁移 1 更改/添加模型
  2. 我们添加/更改一些数据以满足迁移 2 的新逻辑
  3. 我们再次更改模型并创建迁移 3

现在,其中一位开发人员同步了 3 个新的迁移,但由于 models.py 和数据库不匹配而遇到错误。

到目前为止,我们要么伪造了出错的迁移,要么临时更改了依赖项。但是,这既不系统也不方便。

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

以下是问题如何出现的简单示例: 原始模型.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)
    ]

新模型.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

【问题讨论】:

  • 这不应该发生;迁移适用于正是这个用例。这意味着你做错了什么。您应该准确解释当您“遇到由于不匹配导致的错误”时会发生什么。
  • 用可重现的例子修改了问题

标签: python django django-migrations


【解决方案1】:

您没有使用迁移系统提供的功能。特别是,您直接引用了 Test 模型;但是迁移系统包含“历史模型”的概念,它是从迁移到该点动态建立的,因此可以精确地解决这个问题。

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

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

【讨论】:

  • 谢谢!与往常一样,答案是 rtfm ... 将修改问题,以便其他人更容易找到它。
猜你喜欢
  • 2021-02-11
  • 2017-05-02
  • 2014-01-12
  • 2016-06-07
  • 2017-08-26
  • 2017-02-21
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多