2015-07-17 4 views
7

मुझे स्मृति समस्याएं हैं क्योंकि ऐसा लगता है कि delete() का उपयोग करते समय Django स्मृति में वस्तुओं को लोड कर रहा है। क्या Django को ऐसा करने से रोकने का कोई तरीका है?'हटाएं() `का उपयोग करते समय django को स्मृति में वस्तुओं को लोड करने से कैसे रोकें?

Django डॉक्स से:

Django स्मृति में वस्तुओं को लाने के लिए संकेत भेज और झरने संभाल करने की जरूरत है। हालांकि, अगर कोई कैस्केड नहीं है और कोई सिग्नल नहीं है, तो Django स्मृति में लाने के बिना तेजी से पथ ले सकता है और वस्तुओं को हटा सकता है। बड़े डिलीट के लिए इसका परिणाम स्मृति उपयोग में काफी कमी हो सकती है। निष्पादित प्रश्नों की मात्रा भी कम हो सकती है।

https://docs.djangoproject.com/en/1.8/ref/models/querysets/#delete

मैं संकेतों का उपयोग नहीं करते। मेरे पास उस मॉडल पर विदेशी कुंजी है जिसे मैं हटाने की कोशिश कर रहा हूं, लेकिन मुझे नहीं पता कि Django को वस्तुओं को स्मृति में लोड करने की आवश्यकता क्यों होगी। ऐसा लगता है कि ऐसा करता है, क्योंकि मेरी याददाश्त बढ़ती जा रही है क्योंकि क्वेरी चलती है।

+1

चूंकि आपके पास विदेशी कुंजी हैं, इसलिए Django को ऑब्जेक्ट्स को लोड करने की आवश्यकता है ताकि यह हल किया जा सके कि संबंध को हटाने को कैसे संभालना चाहिए: https://docs.djangoproject.com/en/1.8/ref/models/fields/#django .db.models.ForeignKey.on_delete – petkostas

+0

@petkostas मैंने अपने विदेशी क्षेत्रों में 'on_delete = models.DO_NOTHING' डालने का प्रयास किया, लेकिन इससे मदद नहीं मिली। लेकिन यह मेरे लिए अच्छा समाधान नहीं होगा, मैं इस विशिष्ट क्वेरी के लिए स्मृति में वस्तुओं को लोड करना अक्षम करना चाहता हूं, मैं नहीं चाहता कि मेरे सभी प्रश्न विदेशी की बाधाओं को अनदेखा करें .. – rednaw

+0

कच्चे एसक्यूएल का उपयोग समाधान हो सकता है । – NeoWang

उत्तर

0

आप django डेटाबेस कनेक्शन आयात कर सकते हैं और इसे हटाने के लिए एसक्यूएल के साथ इसका उपयोग कर सकते हैं। मेरे पास वही समस्या थी जो आप करते हैं और इससे मुझे बहुत मदद मिलती है। यहाँ कुछ टुकड़ा है (मैं जिस तरह से mysql उपयोग कर रहा हूँ, लेकिन आप किसी भी एसक्यूएल बयान चला सकते हैं):

from django.db import connection 
sql_query = "DELETE FROM usage WHERE date < '%s' ORDER BY date" % date 
cursor = connection.cursor() 
try: 
    cursor.execute(sql_query) 
finally: 
    c.close() 

यह अपने मॉडल रिश्तों में से किसी को प्रभावित किए बिना कि मेज पर ही नष्ट किए गए कार्य पूरे करना चाहिए।

+0

यह संभावना है कि क्वेरी डेटाबेस स्तर पर विफल हो जाएगी, क्योंकि हटाए जा रहे ऑब्जेक्ट्स के पास इंगित करने वाली विदेशी कुंजी हैं, और डीजेगो ने डीबी स्तर पर विदेशी कुंजी पर डिलीट रीस्टिट पर प्रकार की बाधा डाली है। – baxeico

3

आप इस प्रकार का समारोह का उपयोग कर सकते बहुत अधिक स्मृति का उपयोग किए बिना वस्तुओं का एक बड़ी संख्या से अधिक पुनरावृति करने के लिए:

import gc 

def queryset_iterator(qs, batchsize = 500, gc_collect = True): 
    iterator = qs.values_list('pk', flat=True).order_by('pk').distinct().iterator() 
    eof = False 
    while not eof: 
     primary_key_buffer = [] 
     try: 
      while len(primary_key_buffer) < batchsize: 
       primary_key_buffer.append(iterator.next()) 
     except StopIteration: 
      eof = True 
     for obj in qs.filter(pk__in=primary_key_buffer).order_by('pk').iterator(): 
      yield obj 
     if gc_collect: 
      gc.collect() 

तो फिर तुम वस्तुओं से अधिक पुनरावृति करने के लिए समारोह का उपयोग कर सकते नष्ट करने के लिए:

for obj in queryset_iterator(HugeQueryset.objects.all()): 
    obj.delete() 

अधिक जानकारी के लिए आप this blog post देख सकते हैं।

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

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