是否可以手动将django foreignkey ID设置为尚不存在的项目?

时间:2014-09-06 23:41:02

标签: python django

我正在设计从旧系统到基于Django的新系统的批量导入工具。

我想保留对象的所有当前ID(它们只是5位数字符串),现在由于当前系统中的设计,这些对象之间有很多引用。

要导入,我可以看到两种可能的技术 - 导入已知对象,并仔细递归这些关系,确保以正确的方式导入,只有在我知道它们存在时才设置关系

...或者从项目00001开始,将外键设置为我知道存在的值,然后按顺序抓取所有内容,知道一旦我们到达项目99999,所有关系都将存在。

那么有没有办法将外键设置为不存在的项目的ID,但是即使仅用于导入也是如此?

为了进一步增加复杂性,并非所有这些关系都是直接的外键,有些也是ManyToMany关系。

2 个答案:

答案 0 :(得分:1)

为了能够处理Django支持的任何数据库而不必处理后端的特性,我将以Django loaddata可以读取的格式导出旧数据库,然后给出这个导出的文件到loaddata。导入您正在讨论的结构类型时,此命令没有问题。

创建loaddata将读取的文件可以通过编写自己的转换器来读取旧数据库并转储相应的文件来完成。但是,可能更容易的方法是使用与旧数据库中的表具有相同结构的模型创建一次性Django项目,将Django项目指向旧数据库,并使用{ {3}}创建文件。如果旧数据库和新数据库之间的表详细信息已更改,您仍然需要修改该文件,但至少有一些转换工作已经完成。

更直接的方法是完全绕过Django在SQL中导入,但在导入时关闭外键约束。对于MySQL,这可以通过在导入时将dumpdata设置为0,然后在完成时再设置为1来完成。对于SQLite,这将是foreign_key_checks PRAGMA foreign_keys = OFF;,然后ON完成后。

Postgresql不允许仅关闭这些约束,但Django创建外键约束为DEFERRABLE INITIALLY DEFERRED,这意味着直到事务结束才会检查约束。因此,启动事务,导入然后提交应该可行。如果有什么东西阻止了这个,那么你必须在导入之前删除约束并在之后添加它。

答案 1 :(得分:0)

听起来你需要一个数据库迁移工具like South,这是Django的标准。值得注意的是Django 1.7 Beta 1最近发布了,它提供了内置迁移。