1. ホーム
  2. python

Djangoを使用してSQLiteテーブルに数千のレコードを挿入する効率的な方法は何ですか?

2023-11-23 10:33:51

質問

Django の ORM を使って SQLite データベースに 8000 以上のレコードを挿入する必要があります。この操作は、1分間に1回程度、cronjobとして実行する必要があります。

今のところ、私はすべての項目を反復し、それらを1つずつ挿入するためにforループを使用しています。

例として

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

効率的な方法は何でしょうか?

編集してください。 2つの挿入方法を少し比較してみました。

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 ファイルの解析) を行うので、実行に必要な時間は必ずしもレコードの挿入に必要な時間を表しているわけではありません。

どのように解決するのですか?

あなたがチェックアウトしたいのは 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 で、コンテキストマネージャが導入されました。 そのため トランザクション.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 が追加され、モデルオブジェクトのリストを作成し、それらを一度にコミットすることができるようになりました。

ノート の場合、一括作成時に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 では。 トランザクション.アトミック が導入され、現在のレガシー関数である commit_on_successcommit_manually .

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