使用Django将数千条logging插入SQLite表的有效方法是什么?

我必须使用Django的ORM将8000多条logging插入SQLite数据库。 这个操作需要每分钟大约一次的cronjob运行。
目前我正在使用for循环遍历所有项目,然后逐个插入它们。
例:

for item in items: entry = Entry(a1=item.a1, a2=item.a2) entry.save() 

什么是这样做的有效方式?

编辑:两个插入方法之间的一点点比较。

没有commit_manually装饰器(11245logging):

 nox@noxdevel marinetraffic]$ time python manage.py insrec real 1m50.288s user 0m6.710s sys 0m23.445s 

使用commit_manually装饰器(11245logging):

 [nox@noxdevel marinetraffic]$ time python manage.py insrec real 0m18.464s user 0m5.433s sys 0m10.163s 

注意:除了插入到数据库之外, testing脚本还执行一些其他操作(下载ZIP文件,从ZIP压缩文件中提取XML文件,parsingXML文件),因此执行所需的时间不一定代表插入所需的时间logging。

你想检查出django.db.transaction.commit_manually

http://docs.djangoproject.com/en/dev/topics/db/transactions/#django-db-transaction-commit-manually

所以它会是这样的:

 from django.db import transaction @transaction.commit_manually def viewfunc(request): ... for item in items: entry = Entry(a1=item.a1, a2=item.a2) entry.save() transaction.commit() 

哪个只会提交一次,而不是每个save()。

在django 1.3中引入了上下文pipe理器。 所以现在你可以用类似的方式使用transaction.commit_on_success()

 from django.db import transaction def viewfunc(request): ... with transaction.commit_on_success(): for item in items: entry = Entry(a1=item.a1, a2=item.a2) entry.save() 

在django 1.4中, bulk_create被添加,允许你创build你的模型对象的列表,然后一次全部提交它们。

注意使用批量创build时,不会调用save方法。

 >>> Entry.objects.bulk_create([ ... Entry(headline="Django 1.0 Released"), ... Entry(headline="Django 1.1 Announced"), ... Entry(headline="Breaking: Django is awesome") ... ]) 

在django 1.6中,引入了transaction.atomic ,意在替代现在的传统函数commit_on_successcommit_manually

从django primefaces的文档 :

primefaces可用作装饰器:

 from django.db import transaction @transaction.atomic def viewfunc(request): # This code executes inside a transaction. do_stuff() 

作为上下文pipe理者:

 from django.db import transaction def viewfunc(request): # This code executes in autocommit mode (Django's default). do_stuff() with transaction.atomic(): # This code executes inside a transaction. do_more_stuff() 

看看这个 。 它只能用于MySQL的开箱即用,但是有一些关于如何处理其他数据库的指针。

批量加载项目可能会更好 – 准备文件并使用批量加载工具。 这将比8000个单独的插入物高得多。

你应该看看DSE 。 我写了DSE来解决这些问题(大量插入或更新)。 使用django orm是一个死胡同,你必须用普通的SQL来完成,而DSE会为你处理大部分的问题。

托马斯

回答这个问题,特别是关于SQLite的问题,虽然我刚才已经证实bulk_create确实提供了巨大的提速,但SQLite有一个限制:“默认情况下是在一个批处理中创build所有的对象,除了SQLite,默认是这样的,每个查询最多使用999个variables。“

引用的内容来自文档— A-IV提供了一个链接。

我必须补充的是, 这个alpar的djangosnippets入口也似乎为我工作。 这是一个小包装,它将您要处理的大批量分成更小的批次,pipe理999个variables的限制。

我build议使用普通的SQL(而不是ORM),你可以用一个插入插入多行:

 insert into A select from B; 

只要结果与表A中的列匹配,并且不存在约束冲突,那么 SQL的B部分中select可能会像您希望的那样复杂。

我遇到了同样的问题,我想不出没有这么多插入的方法。 我同意使用交易可能是解决这个问题的正确方法,但这里是我的破解:

  def viewfunc(request): ... to_save = []; for item in items: entry = Entry(a1=item.a1, a2=item.a2) to_save.append(entry); map(lambda x: x.save(), to_save);