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

76 投票
9 回答
67613 浏览
提问于 2025-04-15 12:56

我需要通过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 个回答

3

看看这个链接。这个内容主要是为了直接在MySQL上使用的,不过里面也有一些关于如何在其他数据库上使用的提示。

11
132

你可以看看 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_successcommit_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()

撰写回答