DjangoのORMを使用して、8000以上のレコードをSQLiteデータベースに挿入する必要があります。この操作は、cronjobとして約1分に1回実行する必要があります。
現時点では、forループを使用してすべてのアイテムを繰り返し処理し、それらを1つずつ挿入しています。
例:
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
注:testスクリプトは、データベースへの挿入(Zipファイルのダウンロード、XMLファイルの抽出)以外のいくつかの操作も行いますZipアーカイブから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()で1回だけコミットします。
In 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()
In Django 1.4、 bulk_create
が追加され、モデルオブジェクトのリストを作成し、それらを一度にコミットできるようになりました。
[〜#〜] note [〜#〜]一括作成を使用する場合、saveメソッドは呼び出されません。
>>> 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が導入され、現在はレガシー関数commit_on_success
およびcommit_manually
。
Django atomicに関するドキュメント :
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()
一括作成はDjango 1.4で利用できます:
https://Django.readthedocs.io/en/1.4/ref/models/querysets.html#bulk-create
this をご覧ください。これは、MySQLですぐに使用できるように意図されていますが、他のデータベースで何をすべきかについての指針があります。
アイテムを一括ロードする方がよい場合があります-ファイルを準備し、一括ロードツールを使用します。これは、8000個の個別の挿入よりもはるかに効率的です。
[〜#〜] dse [〜#〜] をチェックアウトする必要があります。この種の問題(大量の挿入または更新)を解決するためにDSEを作成しました。 Django ormは行き止まりです。プレーンSQLでそれを行う必要があり、DSEがそのほとんどを処理します。
トーマス
特にSQLiteに関する質問に答えるために、尋ねたように、bulk_createが大幅な高速化を提供することを確認したばかりですが、SQLiteには制限があります。「デフォルトでは、SQLiteを除くすべてのオブジェクトをデフォルトでは、クエリごとに最大999個の変数が使用されます。」
引用されたものはドキュメントからです--- A-IVはリンクを提供しました。
私が追加しなければならないのは、 this djangosnippets alparのエントリも私にとってはうまく機能しているようだということです。 999個の変数の制限を管理して、処理したい大きなバッチを小さなバッチに分割する小さなラッパーです。
def order(request):
if request.method=="GET":
# get the value from html page
cust_name = request.GET.get('cust_name', '')
cust_cont = request.GET.get('cust_cont', '')
pincode = request.GET.get('pincode', '')
city_name = request.GET.get('city_name', '')
state = request.GET.get('state', '')
contry = request.GET.get('contry', '')
gender = request.GET.get('gender', '')
paid_amt = request.GET.get('paid_amt', '')
due_amt = request.GET.get('due_amt', '')
order_date = request.GET.get('order_date', '')
prod_name = request.GET.getlist('prod_name[]', '')
prod_qty = request.GET.getlist('prod_qty[]', '')
prod_price = request.GET.getlist('prod_price[]', '')
# insert customer information into customer table
try:
# Insert Data into customer table
cust_tab = Customer(customer_name=cust_name, customer_contact=cust_cont, gender=gender, city_name=city_name, pincode=pincode, state_name=state, contry_name=contry)
cust_tab.save()
# Retrive Id from customer table
custo_id = Customer.objects.values_list('customer_id').last() #It is return Tuple as result from Queryset
custo_id = int(custo_id[0]) #It is convert the Tuple in INT
# Insert Data into Order table
order_tab = Orders(order_date=order_date, paid_amt=paid_amt, due_amt=due_amt, customer_id=custo_id)
order_tab.save()
# Insert Data into Products table
# insert multiple data at a one time from djanog using while loop
i=0
while(i<len(prod_name)):
p_n = prod_name[i]
p_q = prod_qty[i]
p_p = prod_price[i]
# this is checking the variable, if variable is null so fill the varable value in database
if p_n != "" and p_q != "" and p_p != "":
prod_tab = Products(product_name=p_n, product_qty=p_q, product_price=p_p, customer_id=custo_id)
prod_tab.save()
i=i+1
return HttpResponse('Your Record Has been Saved')
except Exception as e:
return HttpResponse(e)
return render(request, 'invoice_system/order.html')