2011-10-27 12 views
10

मैं Inquiry वस्तुओं की एक बड़ी (300+ एक समय) सूची के लिए Activty ऑब्जेक्ट बनाने की कोशिश कर रहा हूं। मेरे पास एक ModelForm है जिसे वापस पोस्ट किया जा रहा है, और मुझे अलग उदाहरण बनाने की आवश्यकता है, और उन्हें Inquiry पर GenericForeignKey के माध्यम से संलग्न करें। चलो कुछ कोड को प्राप्त करते हैं:थोक डेटाबेस प्रविष्टियां कुशलतापूर्वक बनाएँ?

models.py:

class InquiryEntry(models.Model): 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    entry = generic.GenericForeignKey('content_type', 'object_id') 

class Inquiry(models.Model): 
    entries = models.ManyToManyField('InquiryEntry') 
    # And many more fields. 
    def add_entry(self, obj): 
     entry = self.entries.create(entry=obj) 
     self.save() 
     return entry 

class Activity(models.Model): 
    ts = models.DateTimeField(auto_now_add=True)     
    due_date = models.DateField(auto_now=False) 
    ## And many more fields. 

views.py:

def bulk_create_activities(request): 
    activity_form = ActivityForm() 
    if request.method == "POST": 
     activity_form = ActivityForm(request.POST) 
     if activity_form.is_valid():  
      pks = [int(x) for x in request.POST.get('pks', '').split(',')] 
      for inquiry in Inquiry.objects.filter(pk__in=pks): 
       instance = ActivityForm(request.POST).save() 
       inquiry.add_entry(instance)  
       inquiry.save() 

क्या मैं देख रहा हूँ डेटाबेस में इन डालने के लिए एक रास्ता है , अधिमानतः एक पास में ताकि अनुरोध को तेजी से संसाधित किया जा सके। मैं डेटाबेस स्तर पर नहीं छोड़ना पसंद करता क्योंकि यह एप्लिकेशन एकाधिक डेटाबेस विक्रेताओं में तैनात किया जाता है, लेकिन यदि आगे बढ़ने का यही एकमात्र तरीका है, तो हो (MySQL और Postgres के लिए उदाहरण शानदार होंगे)।


नोट: मुझे पता है कि वहाँ विकास संस्करण में एक bulk_create, लेकिन यह सवाल से बाहर है जब तक वहाँ एक स्थिर रिलीज है।

उत्तर

3

क्या आपने लेनदेन निर्माण में अपने for को बस संलग्न करने का प्रयास किया था? कम्युनिटी ऑन-ट्रांजैक्शन लेन-देन आपको भारी गति से प्राप्त कर सकते हैं क्योंकि प्रविष्टियों को थोक में डिस्क पर एक साथ लिखा जाता है, इसलिए डीबीएमएस को प्रत्येक आइटम के बाद fsync() के लिए रुकना नहीं पड़ता है।

Django के हाल के संस्करणों में लागू करने के लेन-देन तेज़ है, https://docs.djangoproject.com/en/dev/topics/db/transactions/#controlling-transaction-management-in-views

+0

एक अच्छा विचार की तरह लगता है, लेकिन प्रदर्शन में बहुत बदलाव नहीं आया। 5-10 गतिविधियों पर, इसमें लगभग 5% की गति वृद्धि हुई थी। 100 पर, 10% की गति कम हो जाती है। –

+0

सूचक के लिए धन्यवाद। यह एक महान नई सुविधा है। – AgDude

0

की जाँच आप कुछ संकेत (अलग db सिस्टम के लिए सहित) एसक्यूएल Django को देखकर प्राप्त करने में सक्षम हो सकता है कुछ नमूना डेटा के लिए उत्पन्न करता है। डीबग मोड में अपना सर्वर चला रहा है सभी प्रश्न लॉग हैं। आप भी उन्हें के माध्यम से

>>> from django.db import connection 
>>> connection.queries 
0

निरीक्षण कर सकते हैं http://people.iola.dk/olau/python/bulkops.py

पर एक नज़र यह insert_many और update_many कार्य करता है जो किसी एक क्वेरी निष्पादित प्रदान करता है। जैसा कि लेखक ने उल्लेख किया है कि आपको कई रिश्तों में कई लोगों के लिए पाइथन में कुछ मैन्युअल बहीखाता करना होगा, लेकिन एक बार जब आप उन्हें काम कर लेंगे, तो आप आसानी से Inquiry और InquiryEntry पर insert_many के कुछ निष्पादित कर सकते हैं।

0

यह आपकी थोक कार्रवाई को और अधिक कुशल नहीं बनाता है, लेकिन यदि Inquiry को सबमिट किए गए डेटा (मैं मॉडल नाम के आधार पर मान रहा हूं) के आधार पर तत्काल प्रतिक्रिया देने की आवश्यकता नहीं है, तो यह सही की तरह लगता है सेलेरी की तरह एक कार्य कतार के लिए नौकरी।

उपयोगकर्ता को एक तेज तेज़ प्रतिक्रिया मिलेगी, और आपके अजवाइन कर्मचारी अपने अवकाश पर इसे क्रंच कर सकते हैं। जब 1.4 स्थिर है, तो in_bulk देखें :)

मुझे डेटाबेस अज्ञेयवादी रॉक ठोस विधि में रुचि भी होगी, लेकिन आपकी स्थिति के आधार पर यह एक स्वीकार्य समाधान हो सकता है।

देख रहे हो जाएगा जवाब यहां ...

1

मुझे डर है कि आप drop to DB-API करने की जरूरत है और cursor.executemany उपयोग कर सकते हैं (हूँ)। विवरण के लिए PEP 249 देखें।

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