【问题标题】:Django: models setup for using one database to populate anotherDjango:使用一个数据库填充另一个数据库的模型设置
【发布时间】:2021-04-07 07:14:48
【问题描述】:

我正在 Django 中重建一个个人项目(一个家谱),并且我正在努力将实际数据从旧的笨拙数据库迁移到我的新模型/模式,两个 Postgres 数据库。我已在 settings.py 的 DATABASES 列表中将它们定义为“默认”和“源”。

我已经制作了模型,我想将旧数据库中的记录复制到新数据库中的相应表中,但我不太了解如何设置模型以使其工作,因为Django 代码使用模型/ORM 来访问/更新/创建对象,我只有反映新模式的模型,而不是旧模式。

在一个巧合的情况下,我在新旧数据库中有一个具有完全相同架构的表,我有一个管理命令可以使用我的新 ImagePerson 模型 (ported_data = ImagePerson.objects.using('source').all()) 从源中获取旧记录,因为它预期的字段是相同的。然后我将对象保存在“默认”中:(obj, created_bool) = ImagePerson.objects.using('default').get_or_create(field=fieldvalue, etc),它就像我需要的那样工作。

但是当我有一个旧版本的表缺少我的新模型/表所具有的字段时,我无法使用该模型来访问这些记录(这是有道理的)。我是否还应该为每个模型制作某种旧版本以用于迁移?我看到一个教程提到运行./manage.py inspectdb --database=source > models.py,但这样做似乎并没有在我的文件中添加任何其他内容(无论如何在其中保存临时/旧模型似乎很奇怪)。访问旧格式记录的正确方法是什么? ORM 对吗?

举一个具体的例子,我有一个 Notes 表来保存关于特定人或特定家庭的记忆。旧表使用了一个“类型”字段(1 用于个人备注,2 用于家庭备注)和一个 ref_id,它将是备注适用的个人或家庭的 id。新表有一个 person_id 字段和一个 family_id 字段。

我希望我的管理命令能够从源表中提取所有记录,然后如果 type=1,则查找 id 等于 ref_id 字段的人,并在新数据库中保存一个新对象和那个人。我可以使用带有旧数据库的新 Notes 模型来获取它们,如下所示:ported_notes = Note.objects.using('source').all(),但是如果我尝试访问任何字段(如print(note_row.body)),我会收到错误消息,结果对象缺少 person_id 字段

django.db.utils.ProgrammingError: column notes.person_id does not exist

解决这个问题的正确方法是什么?

【问题讨论】:

    标签: python django dbmigrate


    【解决方案1】:

    为旧架构创建模型绝对不是正确的方法。

    一种解决方案是编写数据迁移,您可以使用原始 SQL 获取旧数据,然后使用 ORW 将其写入新表/模型:

    from django.db import migrations, connections
    
    def transfer_data(apps, schema_editor):
        ModelForNewDB = apps.get_model('yourappname', 'ModelForNewDB')
        # Fetch your old data
        with connections['my_old_db'].cursor() as cursor:
            cursor.execute('select * from some_table')
            data = cursor.fetchall()
        
        # Write it to your new models
        for datum in data:
            # do something with the data / add any
            # additional values needed.
            ModelForNewDB.objects.create(...)
    
    
    class Migration(migrations.Migration):
    
        dependencies = [
            ('yourappname', '0001_initial'),
        ]
    
        operations = [
            migrations.RunPython(transfer_data),
        ]
    

    然后只需运行您的迁移。但是需要注意的一件事:

    如果表之间有外键等,则需要注意如何订购迁移。这可以通过编辑您的dependencies 来完成。您甚至可能必须添加一个迁移以允许某些外键为空值,然后再添加另一个以更正此问题。

    【讨论】:

    • 是的,这正是我想做的事情——我会尝试并跟进!
    猜你喜欢
    • 2012-09-05
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多