python - Django:批量操作

标签 python sql django orm bulk

业务:
我遇到了一个问题——当使用 Django ORM 操作大型数据集时,规范的方法是操作每个元素。但是当然这种方式是非常低效的。所以我决定使用原始 SQL。

物质:
我有一个构成 SQL 查询的基本代码,它更新表的行并提交它:

from myapp import Model
from django.db import connection, transaction
COUNT = Model.objects.count()
MYDATA = produce_some_differentiated_data() #Creating individual value for each row
cursor = connection.cursor()
str = []
for i in xrange(1, COUNT):
    str.append("UPDATE database.table\n"
               "SET field_to_modify={}\n"
               "WHERE primary_key_field={};\n".format(MYDATA, i))


str = ''.join(str)
cursor.execute(str)
transaction.commit_unless_managed() #This cause exception

在最后一条语句中我得到了这个,即使 SIZE 很小:

_mysql_exceptions.ProgrammingError: (2014, "Commands out of sync; you can't run this command now")

也许 Django 不允许一次执行多个 SQL 查询?

附言 在提交前关闭游标有助于避免异常,但这是正确的吗?

我的期望:
我正在寻找批量操作的所有可能的可靠解决方案(最好在 Django 内部)。 我不关心它是 ORM 还是原始 SQL,如果我能避免错误,我会支持上面粘贴的代码。如果没有解决方案,至少出于好奇,了解此异常的原因会很好。

除了答案我还学到了什么:
在 Django 1.4 中引入了 bulk_create , 用于高效的多个 INSERT 操作

最佳答案

Django 1.4+ 在它的 ORM 中对批量操作有相当不错的支持,你应该看看你是否可以使用它——它是最便携的方式,也非常好用。

它不仅允许为所有对象中的字段更新相同的值(这是微不足道的),还允许基于其他字段更新字段值以及执行一些有限的计算。我不确定它是否符合您的需要(取决于“produce_some_differentiated_data”的工作方式)-您可以进行一些计算,其中一些可能不会。一些例子:

image_id_list = [1,5,6]
Image.objects.filter(image_id__in=image_id_list).
     update(views_number=F('views_number') + 1)

上面的例子会转换成类似如下的SQL:

UPDATE image SET views_number = views_number + 1 WHERE image_id IN (1,5,6);

这是执行批量更新最快的方法 - 比运行多个查询快得多。在单个 SQL 语句中运行多个查询并不能真正提高操作速度。改进它的是像上面这样同时对多行进行操作的单个查询。您可以在更新语句中构建相当复杂的公式,因此如果您的“produce_some_differentiated_data”方法可以用这种方式表达,那将是最好的。即使不能直接完成,您也可以对模型进行一些修改并添加一些额外的字段来实现。如果经常执行此类批量操作,这可能会有所返回。

来自 Django 的文档:

Django supports the use of addition, subtraction, multiplication, division and modulo arithmetic with F() objects, both with constants and with other F() objects.

更多相关信息: https://docs.djangoproject.com/en/dev/topics/db/queries/#updating-multiple-objects-at-once

关于python - Django:批量操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14035198/

相关文章:

c# - 访问数据和连接字符串?

python - 我正在编写一个学生成绩跟踪器,但不知道如何将学生添加到数据库中

python - 如何配置 tox 以获取日志

java - 带证书的 SSL 连接

sql - 附加两个查询的结果并输出为单个表

python - 将字典列表合并为一个的更多 Pythonic 方式?

python - ipython 就像 ruby​​ 的解释器

java - 使用 postgres 和 jooq 按时间分组

python - 有没有一种优雅的方法将 {% if .. %} 应用于 Django 中的整个标签负载?

python - 在 Django View 中寻找 get_or _create 的良好示例用法并引发表单错误