在 Django 1.7 迁移中调用 loaddata 会抛出“‘字段列表’中的未知列‘[字段]’”

Posted

技术标签:

【中文标题】在 Django 1.7 迁移中调用 loaddata 会抛出“‘字段列表’中的未知列‘[字段]’”【英文标题】:Calling loaddata in Django 1.7 migrations is throwing "Unknown column '[field]' in 'field list'" 【发布时间】:2015-05-23 05:11:36 【问题描述】:

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

    为应用创建模型的初始架构迁移 在包含一次性默认数据的特定夹具上调用 loaddata 的数据迁移 向其中一个模型添加了一个新的可选字段,因此添加该字段是一种架构迁移

如果我生成第一个迁移,运行它,生成第二个,运行它,然后添加新字段,生成第三个迁移,然后运行它,一切都很好。但是,如果我的数据库在迁移 #1 上,然后我从源存储库中下拉,则迁移 2 将失败,因为它在调用 loaddata 时使用来自 models.py 的模型,而不是在迁移时使用模型。然后它会产生以下错误:

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

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

谢谢。

【问题讨论】:

【参考方案1】:

我最终写了一个 hack 来解决这个问题,但我觉得必须有更好的方法。我现在调用这个函数,而不是在迁移中调用 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__)

有人知道更好的方法吗?感觉真的很像黑客,因为我必须访问对象元数据才能完成此操作。

【讨论】:

以上是关于在 Django 1.7 迁移中调用 loaddata 会抛出“‘字段列表’中的未知列‘[字段]’”的主要内容,如果未能解决你的问题,请参考以下文章

Django 1.7 内置迁移与南迁移?

Django 1.7 中的迁移

Django 1.7 中的 Django-migrations 检测模型更改,但不会在迁移时应用它们

为啥 django 1.7 会为字段选择的变化创建迁移?

Django 1.7(显然)没有在 manage.py 测试中运行迁移

Django 1.7 迁移不会重新创建删除的表,为啥?