使用Django高效插入数千条记录到SQLite表的方法是什么?
我需要通过Django的ORM把8000多个记录插入到SQLite数据库里。这项操作需要每分钟作为一个定时任务运行一次。
目前我使用一个循环来遍历所有的项目,然后一个一个地插入。
举个例子:
for item in items:
entry = Entry(a1=item.a1, a2=item.a2)
entry.save()
有没有更有效的方法来做到这一点呢?
编辑:对比一下两种插入方法。
没有使用commit_manually装饰器的情况下(11245条记录):
nox@noxdevel marinetraffic]$ time python manage.py insrec
real 1m50.288s
user 0m6.710s
sys 0m23.445s
使用commit_manually装饰器的情况下(11245条记录):
[nox@noxdevel marinetraffic]$ time python manage.py insrec
real 0m18.464s
user 0m5.433s
sys 0m10.163s
注意:这个测试脚本除了插入数据库外,还做了一些其他操作(下载一个ZIP文件,从ZIP文件中提取一个XML文件,解析这个XML文件),所以执行所需的时间并不一定代表插入记录所需的时间。
9 个回答
看看这个链接。这个内容主要是为了直接在MySQL上使用的,不过里面也有一些关于如何在其他数据库上使用的提示。
在Django 1.4中,可以进行批量创建:
https://django.readthedocs.io/en/1.4/ref/models/querysets.html#bulk-create
你可以看看 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 版本中,引入了上下文管理器的概念。现在你可以用 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
功能,这样你可以一次性创建多个模型对象,然后一起提交。
注意 使用 bulk create 时,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_success
和 commit_manually
。
关于 atomic 的详细信息可以参考 Django 的 文档:
atomic 可以作为装饰器使用:
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
也可以作为上下文管理器使用:
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()