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

67 python sql sqlite django insert

我必须使用Django的ORM将8000多条记录插入到SQLite数据库中.此操作需要每分钟大约运行一次cronjob.
目前我正在使用for循环迭代所有项目,然后逐个插入它们.
例:

for item in items:
    entry = Entry(a1=item.a1, a2=item.a2)
    entry.save()
Run Code Online (Sandbox Code Playgroud)

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

编辑:两种插入方法之间的一点比较.

没有commit_manually装饰器(11245条记录):

nox@noxdevel marinetraffic]$ time python manage.py insrec             

real    1m50.288s
user    0m6.710s
sys     0m23.445s
Run Code Online (Sandbox Code Playgroud)

使用commit_manually decorator(11245条记录):

[nox@noxdevel marinetraffic]$ time python manage.py insrec                

real    0m18.464s
user    0m5.433s
sys     0m10.163s
Run Code Online (Sandbox Code Playgroud)

注意:除了插入数据库之外,测试脚本还执行一些其他操作(下载ZIP文件,从ZIP存档中提取XML文件,解析XML文件),因此执行所需的时间不一定代表插入所需的时间记录.

mon*_*kut 120

你想看看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()
Run Code Online (Sandbox Code Playgroud)

这将只提交一次,而不是每次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()
Run Code Online (Sandbox Code Playgroud)

在django 1.4中,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")
... ])
Run Code Online (Sandbox Code Playgroud)

在django 1.6中,引入了transaction.atomic,旨在取代现在的遗留功能commit_on_successcommit_manually.

来自关于原子的django 文档:

原子可用作装饰器:

from django.db import transaction

@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()
Run Code Online (Sandbox Code Playgroud)

并作为上下文管理器:

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()
Run Code Online (Sandbox Code Playgroud)

  • 这将它们全部实例化为模型,并运行数千个单独的插入.我总是不得不放弃SQL并为这种类型的卷进行手动批量插入; Django不是为它而建的.但是,如果你这样做的话,你肯定想要一笔交易. (7认同)
  • 现在Django 1.4已经出局了,使用https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.bulk_create会更有意义.另一个快速的替代方法是手动创建批量SQL插入.这里的提示(在一个事务中提交)将不会像发送一个插入那样快. (3认同)
  • 我没有.net经验,但从一般的数据库角度来看,关闭AUTOCOMMIT并在BEGIN/END TRANSACTION语句之间封装INSERT语句将比使用AUTOCOMMIT和单独运行INSERTS更快.请注意,这些命令及其使用方式可能会根据您使用的数据库而改变.如果您想要.net或.net框架,请继续进行特定的回答并开始一个新问题. (2认同)
  • 从1.9开始,bulk_create工作得很好.请注意,您需要将创建分解为批次,SQLite的总添加属性不超过999. (2认同)