我需要能够快速批量快速地批量插入大量记录,同时仍然确保数据库中的唯一性。要插入的新记录已经过解析,并且是唯一的。我希望有一种方法可以在数据库级别强制执行唯一性,而不是代码本身。
我正在使用MySQL作为数据库后端。如果django在任何其他数据库中支持此功能,我可以灵活地更改后端,因为这是一项要求。
Django中的批量插入不使用save
方法,因此如何一次插入数百到数千条记录,同时仍然尊重唯一字段和唯一的字段?
我的模型结构,简化,看起来像这样:
class Example(models.Model):
Meta:
unique_together = (('name', 'number'),)
name = models.CharField(max_length = 50)
number = models.CharField(max_length = 10)
...
fk = models.ForeignKey(OtherModel)
修改
应插入数据库中尚未存在的记录,并应忽略已存在的记录。
答案 0 :(得分:1)
正如miki725所提到的,您的当前代码没有问题。 我假设您使用的是 bulk_create 方法。确实在使用bulk_create时没有调用save()方法,但是在save()方法中没有强制执行字段的唯一性。当您使用unique_together时,在创建表时,会在mysql的基础表中添加唯一约束:
Django的:
unique_together = (('name', 'number'),)
MySQL的:
UNIQUE KEY `name` (`name`,`number`)
因此,如果使用任何方法(save,bulk_insert甚至原始sql)将值插入表中,您将从mysql中获取此异常:
Duplicate entry 'value1-value2' for key 'name'
<强>更新强>
bulk_insert的作用是创建一个大查询,通过一个查询一次性插入所有数据。因此,如果其中一个条目是重复的,则会抛出异常,并且不会插入任何数据。
1-一个选项是使用bulk_insert的batch_size参数并使其以多个批次插入数据,这样如果其中一个失败,您只会错过该批次的其余数据。 (取决于插入所有数据的重要性以及重复条目的频率)
2-另一种选择是在批量数据上写一个for循环,然后逐个插入批量数据。这样,仅为该行抛出异常,并插入其余数据。这将每次查询数据库,当然慢很多。
3-第三个选项是解除唯一约束,使用bulk_create插入数据,然后编写一个删除重复行的简单查询。
答案 1 :(得分:0)
Django本身不强制执行unique_together
元属性。这是由数据库使用UNIQUE
子句强制执行的。您可以根据需要插入尽可能多的数据,并确保指定的字段是唯一的。如果没有,那么将引发异常(不确定是哪一个)。有关docs中unique_together
的更多信息。