在Django 1.7迁移中调用loaddata会导致"未知列' [field]'在'字段列表'"

时间:2015-03-19 21:46:15

标签: django django-1.7 django-migrations django-fixtures

在尝试连续编写多个迁移时,我在Django 1.7中遇到了一个问题。以下是迁移的基本设置:

  1. 为应用创建模型的初始架构迁移
  2. 在包含一次性默认数据的特定灯具上调用loaddata的数据迁移
  3. 其中一个模型添加了一个新的可选字段,因此它是一个添加字段的模式迁移
  4. 如果我生成第一个迁移,运行它,生成第二个,运行它,然后添加新字段,生成第三个迁移,并运行它,一切都很好。但是,如果我的数据库是迁移#1,然后我从源存储库中下载,则迁移2将失败,因为它在调用loaddata时使用models.py中的模型,而不是在迁移时调用模型。然后它会产生以下错误:

    "Unknown column '[field]' in 'field list'"
    

    在这种情况下,[field]是我为迁移#3添加的新字段。错误是有道理的,因为我的数据库还没有新字段,但loaddata期望它在那里(即使夹具没有引用新字段),但有没有办法使loaddata使用数据库在迁移的时间而不是models.py中的当前状态?或者还有其他方法可以解决这个问题吗?

    感谢。

1 个答案:

答案 0 :(得分:0)

我现在最终写了一个黑客来解决这个问题,但我觉得必须有一个更好的方法。我现在调用这个函数,而不是在迁移中调用loaddata:

def load_fixture_in_data_migration(apps, schema_editor, fixture_filename, migration_file):
"""
Load fixture data in data migrations without breaking everything
when the models change later on
"""
fixture_dir = os.path.abspath(os.path.join(os.path.dirname(migration_file), '../fixtures'))
fixture_file = os.path.join(fixture_dir, fixture_filename)

fixture = open(fixture_file, 'rb')
objects = serializers.deserialize('json', fixture, ignorenonexistent=True)
for obj in objects:
    ObjApp = apps.get_model(obj.object._meta.app_label, obj.object._meta.object_name)
    new_obj = ObjApp(pk=obj.object.pk)
    for field in ObjApp._meta.fields:
        setattr(new_obj, field.name, getattr(obj.object, field.name))
    new_obj.save()
fixture.close()

我从数据迁移中这样称呼它:

load_fixture_in_data_migration(apps, schema_editor, 'initial_add_ons.json', __file__)

有谁知道更好的方法吗?感觉真的像黑客,因为我必须访问对象元数据才能实现这一点。