Django 数据迁移与 models.py 不匹配
Django data migration mismatch with models.py
我们在项目中使用 django 1.8 和迁移,我们 运行 反复遇到以下问题:
- 我们 change/add 迁移模型 1
- 我们add/change一些数据来满足迁移 2 的新逻辑
- 我们再次更改模型并创建迁移 3
现在,其中一位开发人员同步了 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)
]
新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'),
),
]
运行ning migrate
导致 django.db.utils.OperationalError: table Test_test has no column named c
而 运行ning 第二次迁移。
您没有使用迁移系统提供的功能。特别是,您直接引用了测试模型;但是迁移系统包含 "historical models" 的概念,它是从迁移到那个点动态构建的,因此精确地解决了这个问题。
documentation 进一步解释了这一点,但基本上不是在迁移 0002 中导入测试,而是动态获取它:
def testData(apps, schema_editor):
Test = apps.get_model("myapp", "Test")
Test.objects.create(a="aaaa", b="bbb")
我们在项目中使用 django 1.8 和迁移,我们 运行 反复遇到以下问题:
- 我们 change/add 迁移模型 1
- 我们add/change一些数据来满足迁移 2 的新逻辑
- 我们再次更改模型并创建迁移 3
现在,其中一位开发人员同步了 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)
]
新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'),
),
]
运行ning migrate
导致 django.db.utils.OperationalError: table Test_test has no column named c
而 运行ning 第二次迁移。
您没有使用迁移系统提供的功能。特别是,您直接引用了测试模型;但是迁移系统包含 "historical models" 的概念,它是从迁移到那个点动态构建的,因此精确地解决了这个问题。
documentation 进一步解释了这一点,但基本上不是在迁移 0002 中导入测试,而是动态获取它:
def testData(apps, schema_editor):
Test = apps.get_model("myapp", "Test")
Test.objects.create(a="aaaa", b="bbb")