2010-08-03 7 views
31

मैं एक स्क्लाइट बैकएंड के साथ Django का उपयोग कर रहा हूं, और प्रदर्शन लिखना एक समस्या है। मैं कुछ स्तर पर "उचित" डीबी में स्नातक हो सकता हूं, लेकिन इस पल के लिए मैं स्क्लाइट के साथ फंस गया हूं। मुझे लगता है कि मेरी लेखन प्रदर्शन समस्याएं शायद इस तथ्य से संबंधित हैं कि मैं बड़ी संख्या में पंक्तियां बना रहा हूं, और संभावित रूप से प्रत्येक बार जब मैं save() डिस्क पर डीबी को अनलॉक और सिंक कर रहा हूं।Django में बचत() एस एकत्रित करना?

मैं एक बड़ी संख्या में save() कॉल को एक डेटाबेस ऑपरेशन में कैसे जोड़ सकता हूं?

+0

http://stackoverflow.com/questions/1136106/efficent-way-to-insert-thousands-of-records-into-a-table-sqlite-python-django –

+0

@ टोमाज़ - लिंक के लिए धन्यवाद, @commit_manually सजावटी मुझे मुझे आवश्यक प्रदर्शन सुधार देता है। मैंने अपने प्रश्न को एक डुप्ली के रूप में बंद करने के लिए चिह्नित किया है क्योंकि मुझे लगता है कि दूसरा इसे अच्छी तरह से कवर करता है। – kdt

+0

आप वास्तव में बंद करने के लिए मतदान करने के बजाए अपना प्रश्न बंद कर सकते हैं, आपको पता है। –

उत्तर

54

वास्तव में ऐसा करना आसान है, तो आपको लगता है। आप Django में transactions का उपयोग कर सकते हैं। इन बैच डेटाबेस संचालन (विशेष रूप से सहेजें, डालें और हटाएं) एक ऑपरेशन में। मुझे उपयोग करने का सबसे आसान उपयोग commit_on_success है। अनिवार्य रूप से आप अपने डेटाबेस को ऑपरेशन को एक फ़ंक्शन में सहेजते हैं और फिर commit_on_success सजावट का उपयोग करते हैं।

from django.db.transaction import commit_on_success 

@commit_on_success 
def lot_of_saves(queryset): 
    for item in queryset: 
     modify_item(item) 
     item.save() 

इसमें बहुत तेज वृद्धि होगी। यदि कोई आइटम विफल हो जाता है तो आपको रोल-बैक होने का लाभ भी मिलेगा। यदि आपके पास लाखों बचत कार्य हैं तो आपको commit_manually और transaction.commit() का उपयोग करके उन्हें ब्लॉक में लेना पड़ सकता है लेकिन मुझे शायद ही कभी इसकी आवश्यकता है।

आशा है कि मदद करता है,

विल

+0

यह लगभग जादुई था। मैंने एक यादृच्छिक फ़ंक्शन लपेट लिया जो बहुत सारे रिकॉर्ड बनाता है, और यह तुरंत SQLite में कई गुना तेजी से बन गया। – alberge

+32

आप में से उन लोगों के लिए जो अभी इस उत्तर में चल रहे हैं, 'commit_ऑन_सुईसीई' अब बहिष्कृत है। इसके बजाय, इसे 'परमाणु' के साथ बदलें, जो कि नया संस्करण है और उसी जादुई प्रभाव का होगा! – Pterosaur

+7

'परमाणु 'संदर्भ: https://docs.djangoproject.com/en/dev/topics/db/transactions/#django.db.transaction.atomic – Paolo

1

"मैं एक डेटाबेस संख्या में बड़ी संख्या में बचत() कॉल कैसे एकत्र कर सकता हूं?"

आपको इसकी आवश्यकता नहीं है। Django पहले से ही आपके लिए एक कैश का प्रबंधन करता है। आप बचाते हुए चारों ओर झगड़ा करने की कोशिश करके डीबी कैशिंग में सुधार नहीं कर सकते हैं।

सही "लिखने प्रदर्शन की समस्याओं शायद इस तथ्य है कि मैं पंक्तियों की एक बड़ी संख्या तैयार कर रहा हूँ से जुड़े हुए हैं।"

SQLite बहुत धीमी है। ऐसा ही है। अधिकांश डीबी की तुलना में क्वेरी तेज हैं। लेखन बहुत धीमी हैं।

अधिक गंभीर आर्किटेक्चर परिवर्तन पर विचार करें। क्या आप वेब लेनदेन के दौरान पंक्तियां लोड कर रहे हैं (यानी, थोक अपलोड करने वाली फाइलें और उन फ़ाइलों से डीबी लोड करना)?

यदि आप वेब लेनदेन के अंदर थोक लोडिंग कर रहे हैं, तो रोकें। आपको कुछ बेहतर करने की ज़रूरत है। celery का उपयोग करें या पृष्ठभूमि में अपने भार करने के लिए कुछ अन्य "बैच" सुविधा का उपयोग करें।

हम वेब लेनदेन में सत्यापन दर्ज करने के लिए खुद को सीमित करने की कोशिश करते हैं और जब उपयोगकर्ता HTML के अपने पृष्ठ की प्रतीक्षा नहीं कर रहा है तो लोड करें।

+1

हालांकि यह स्पष्ट करना उचित है कि स्क्लाइट वास्तव में स्वाभाविक रूप से है डिस्क का उपयोग करने के तरीके के कारण लिखने पर धीमा, यह * यह * धीमा नहीं होना चाहिए: जैसा कि एक टिप्पणीकर्ता द्वारा सुझाया गया है, मैंने @commit_manually सजावटी का उपयोग शुरू किया और वास्तव में पर्याप्त सुधार पाया। – kdt

41

नई Django 1.6 के रूप में atomic, a simple API to control DB transactions है।डॉक्स से शब्दशः कॉपी किया गया:

from django.db import transaction 

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

और context manager एक के रूप में: django.db.transaction कार्यों autocommit(), commit_on_success(), और commit_manually() पदावनत किया गया है और

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

विरासत

परमाणु दोनों एक decorator के रूप में प्रयोग करने योग्य है Django 1.8 में हटा दिया जाएगा।

संबंधित मुद्दे