3

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

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

编辑:

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

4

2 回答 2

1

正如miki725 所提到的,您当前的代码没有问题。我假设您正在使用bulk_create方法。确实,在使用 bulk_create 时不会调用 save() 方法,但在 save() 方法内部并未强制执行字段的唯一性。当您使用 unique_together 时,在创建表时将唯一约束添加到 mysql 中的基础表:

姜戈:

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 插入数据,然后编写一个删除重复行的简单查询。

于 2013-03-07T05:07:28.197 回答
0

Django 本身并不强制执行unique_togethermeta 属性。这是由数据库使用该UNIQUE子句强制执行的。您可以根据需要插入尽可能多的数据,并保证指定的字段是唯一的。如果不是,那么将引发异常(不确定是哪一个)。unique_together有关文档的更多信息。

于 2013-03-07T04:27:04.720 回答