使用Django将数千条记录插入SQLite表的有效方法是什么? [英] What is an efficient way of inserting thousands of records into an SQLite table using Django?

查看:114
本文介绍了使用Django将数千条记录插入SQLite表的有效方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须使用Django的ORM将8000多个记录插入SQLite数据库。此操作需要作为cronjob大约每分钟运行一次。

目前,我正在使用for循环遍历所有项,然后将它们逐个插入。

示例:

 对于项目中的项目:
entry = Entry(a1 = item.a1,a2 = item .a2)
entry.save()

有效的方法是什么?



编辑:两种插入方法之间的比较。



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

  nox @ noxdevel marinetraffic] $时间python manage.py insrec 

实际1m50.288s
用户0m6.710s
sys 0m23.445s

commit_manually装饰器(11245条记录):

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

实际0m18.464s
用户0m5.433s
sys 0m10.163s

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

解决方案

您要签出 django.db.transaction.commit_manually


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


因此它类似于:

 <来自django.db的code>导入事务

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

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


在Django 1.3中,引入了上下文管理器。
因此,现在您可以使用 transaction.commit_on_success() ,以类似的方式:

 来自django.db导入事务

def viewfunc(request):
...
with transaction.commit_on_success():
用于项目中的项目:
entry = Entry(a1 = item.a1,a2 = item.a2)
entry.save()

在Django 1.4中, bulk_create 已添加,允许您创建模型对象列表,然后一次提交所有对象。


注意

 >> Entry.objects.bulk_create([
... Entry(headline = Django 1.0已发布)),
... Entry(headline = Django 1.1已发布),
。 .. Entry(headline = Breaking:Django is awesome)
...])

在django 1.6, transaction.atomic 被引入,旨在取代现在的旧版功能 commit_on_success commit_manually

django中的

有关原子的文档


atomic都可用作装饰器:

  from django.db导入事务

@ transaction.atomic
def viewfunc(request):
#此代码在事务内执行。
do_stuff()

并作为上下文管理器:


<$ p $来自django.db的p> 导入事务

def viewfunc(request):
#此代码在自动提交模式下执行(Django默认)。
do_stuff()

与transaction.atomic():
#此代码在事务内执行。
do_more_stuff()


I have to insert 8000+ records into a SQLite database using Django's ORM. This operation needs to be run as a cronjob about once per minute.
At the moment I'm using a for loop to iterate through all the items and then insert them one by one.
Example:

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

What is an efficient way of doing this?

Edit: A little comparison between the two insertion methods.

Without commit_manually decorator (11245 records):

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

real    1m50.288s
user    0m6.710s
sys     0m23.445s

Using commit_manually decorator (11245 records):

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

real    0m18.464s
user    0m5.433s
sys     0m10.163s

Note: The test script also does some other operations besides inserting into the database (downloads a ZIP file, extracts an XML file from the ZIP archive, parses the XML file) so the time needed for execution does not necessarily represent the time needed to insert the records.

解决方案

You want to check out django.db.transaction.commit_manually.

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

So it would be something like:

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()

Which will only commit once, instead at each save().

In django 1.3 context managers were introduced. So now you can use transaction.commit_on_success() in a similar way:

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()

In django 1.4, bulk_create was added, allowing you to create lists of your model objects and then commit them all at once.

NOTE the save method will not be called when using bulk create.

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

In django 1.6, transaction.atomic was introduced, intended to replace now legacy functions commit_on_success and commit_manually.

from the django documentation on atomic:

atomic is usable both as a decorator:

from django.db import transaction

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

and as a context manager:

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()

这篇关于使用Django将数千条记录插入SQLite表的有效方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆