2009-03-25 16 views
7

एक अंतरिक्ष विजय खेल के लिए एक models.py के निम्नलिखित कंकाल पर विचार करें:Django ORM: कैशिंग और जोड़ तोड़ ForeignKey वस्तुओं

class Fleet(models.Model): 
    game = models.ForeignKey(Game, related_name='planet_set') 
    owner = models.ForeignKey(User, related_name='planet_set', null=True, blank=True) 
    home = models.ForeignKey(Planet, related_name='departing_fleet_set') 
    dest = models.ForeignKey(Planet, related_name='arriving_fleet_set') 
    ships = models.IntegerField() 

class Planet(models.Model): 
    game = models.ForeignKey(Game, related_name='planet_set') 
    owner = models.ForeignKey(User, related_name='planet_set', null=True, blank=True) 
    name = models.CharField(max_length=250) 
    ships = models.IntegerField() 

मैं एक परियोजना के लिए कई तरह के डेटा मॉडल मैं पर काम कर रहा हूँ, और मुझे विभिन्न डेटा ऑब्जेक्ट्स के बीच कुछ जटिल इंटरैक्शन के आधार पर गेम की स्थिति बदलें। मैं डेटाबेस के लिए अनावश्यक कॉल से बचने का है, तो एक बार बारी प्रति, मैं

  1. क्वेरी की तरह कुछ करने के सभी बेड़े, ग्रहों, और अन्य डेटाबेस से वस्तुओं और
  2. प्रक्रिया उन्हें अजगर वस्तुओं के रूप में कैश चाहते खेल वस्तुओं, खेल
  3. के राज्य को हल करने के लिए उन्हें सहेजें डेटाबेस

में वापस आ गया है जब यह मॉडल ForeignKey वस्तुओं का उपयोग कर पूरी तरह से टूट रहा है। उदाहरण के लिए, जब एक नया बेड़ा एक ग्रह रवाना, मैं एक लाइन है कि कुछ इस तरह दिखता है:

fleet.home.ships -= fleet.ships 

इस लाइन चलाता है के बाद, मैं अन्य कोड है कि ग्रहों में से प्रत्येक में जहाजों की संख्या को बदल देता है, सहित ग्रह बेड़े। कुछ। दुर्भाग्यवश, उपर्युक्त रेखा में किए गए परिवर्तन पहले ग्रहण किए गए ग्रहों के क्वेरीसेट में प्रतिबिंबित नहीं होते हैं, ताकि जब मैं बारी के अंत में सभी ग्रहों को सहेजूं, तो बेड़े में परिवर्तन हो जाएंगे। कुछ जहाजों को अधिलेखित किया जाता है।

इस स्थिति से निपटने में कुछ बेहतर तरीका है? या यह सिर्फ सभी ओआरएम कैसे हैं?

उत्तर

20

Django के ORM को लागू नहीं करता है एक identity map (यह ticket tracker में है, लेकिन यह स्पष्ट नहीं है कि या जब यह लागू किया जाएगा नहीं है, कम से कम एक कोर Django committer expressed opposition to it है)। इसका अर्थ यह है कि यदि आप दो अलग-अलग क्वेरी पथों के माध्यम से एक ही डेटाबेस ऑब्जेक्ट पर पहुंचते हैं, तो आप स्मृति में विभिन्न पायथन ऑब्जेक्ट्स के साथ काम कर रहे हैं।

इसका मतलब यह है कि आपके डिजाइन (एक ही बार में स्मृति में सब कुछ लोड करते हैं, बहुत कुछ संशोधित करते हैं तो अंत में यह सब वापस बचाने के लिए) Django ORM का उपयोग कर असाध्य है। सबसे पहले क्योंकि यह अक्सर एक ही ऑब्जेक्ट की डुप्लिकेट प्रतियों में बहुत सारी मेमोरी लोडिंग को बर्बाद कर देगा, और दूसरी बार "ओवरराइटिंग" समस्याओं की वजह से आप जिस पर चल रहे हैं।

आप या तो अपने डिजाइन फिर से काम करने के लिए (इन समस्याओं से बचने की जरूरत है या तो एक समय में केवल एक क्वेरीसमूह के साथ काम करने के लिए सावधान रहना, संशोधित करने से पहले आप किसी अन्य क्वेरी बनाने के लिए कुछ भी बचत, या अगर आपके पास कई प्रश्नों लोड, मैन्युअल रूप से सभी संबंधों को देखने के , उनके लिए सुविधाजनक विशेषताओं का उपयोग करके विदेशीकिज़ों को कभी भी पार न करें), या एक वैकल्पिक पायथन ओआरएम का उपयोग करें जो पहचान मानचित्र लागू करता है। SQLAlchemy एक विकल्प है।

ध्यान दें कि यह Django के ORM मतलब यह नहीं है "बुरा है।" यह वेब अनुप्रयोगों के मामले में अनुकूलित है, जहां इस तरह के मुद्दे दुर्लभ हैं (मैंने वर्षों से Django के साथ वेब विकास किया है और कभी भी एक वास्तविक परियोजना पर यह समस्या नहीं थी)। यदि आपका उपयोग केस अलग है, तो आप एक अलग ओआरएम चुनना चाहेंगे।

+1

अच्छी तरह से संक्षेप –

+0

हाँ, आप इस जानकारीपूर्ण प्रतिक्रिया के लिए बहुत बहुत धन्यवाद।मुझे पता है कि इसका मतलब यह नहीं है कि Django का ओआरएम खराब है; वास्तव में, मैंने Django का उपयोग करके एक संपूर्ण परियोजना विकसित की है जिसे इस तरह के जटिल डेटा प्रोसेसिंग की आवश्यकता नहीं है, और यह समस्या कभी नहीं आई है, यही कारण है कि मैं इस तरह के नुकसान पर था। –

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