Django Unique Bulk Inserts

时间:2013-03-07 02:11:51

标签: django django-models django-database

我需要能够快速批量快速地批量插入大量记录,同时仍然确保数据库中的唯一性。要插入的新记录已经过解析,并且是唯一的。我希望有一种方法可以在数据库级别强制执行唯一性,而不是代码本身。

我正在使用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)

修改

应插入数据库中尚未存在的记录,并应忽略已存在的记录。

2 个答案:

答案 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子句强制执行的。您可以根据需要插入尽可能多的数据,并确保指定的字段是唯一的。如果没有,那么将引发异常(不确定是哪一个)。有关docsunique_together的更多信息。