2011-07-28 13 views
7

का उपयोग करके डुप्लिकेट टेबल्स समेत मैं Django के ORM का उपयोग करके एक साधारण ट्रिपलस्टोर को लागू करने की कोशिश कर रहा हूं। मैं मनमाने ढंग से जटिल ट्रिपल पैटर्न (जैसे आप SparQL के साथ करेंगे) की खोज करने में सक्षम होना चाहते हैं।Django के ORM अतिरिक्त()

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

class Triple(models.Model): 
    subject = models.CharField(max_length=100) 
    predicate = models.CharField(max_length=100) 
    object = models.CharField(max_length=100) 

और मैं निम्नलिखित ट्रिपल मेरी डेटाबेस में संग्रहीत है:

उदाहरण के लिए, मैं अपने "ट्रिपल" ऐप्लिकेशन में निम्नलिखित मॉडल है कहना

subject predicate object 
bob has-a hat . 
bob knows sue . 
sue has-a house . 
bob knows tom . 
अब

, कहते हैं कि मैं चाहता हूँ हर किसी के नाम पूछने के लिए बॉब जानता है कि किसके पास घर है। एसक्यूएल में, मैं बस करना चाहते हैं:

q = Triple.objects.filter(subject='bob', predicate='knows') 
q = q.extra(tables=['triple_triple'], where=["triple_triple.object=t1.subject AND t1.predicate = 'has-a' AND t1.object = 'house'"]) 
q.values('t1.subject') 

दुर्भाग्य:

SELECT t2.subject AS name 
FROM triple_triple t1 
INNER JOIN triple_triple t2 ON 
    t1.subject = 'bob' 
AND t1.predicate = 'knows' 
AND t1.object = t2.subject 
AND t2.predicate = 'has-a' 
AND t2.object = 'house' 

मैं हालांकि मुझे लगता है कि यह की तर्ज पर हो सकता है, पूरी तरह से यकीन है कि यह Django के ORM के साथ नज़र आएंगे नहीं कर रहा हूँ , इस त्रुटि के साथ विफल "DatabaseError: ऐसी कोई स्तंभ: t1.subject"

प्रिंट q.query चल रहा है पता चलता है:

SELECT "triple_triple"."subject" FROM "triple_triple" WHERE ("triple_triple"."subject" = 'bob' AND "triple_triple"."predicate" = 'knows' 
AND triple_triple.object = t1.subject AND t1.predicate = 'has-a' AND t1.object = 'house') 

जो दिखाता प्रतीत होता है कि मेरे कॉल में एक्स्ट्रा() को पैरामीटर को अनदेखा किया जा रहा है, क्योंकि कहीं भी ट्रिपल_ट्रियल को सम्मिलित करने का कोई दूसरा संदर्भ नहीं है।

ऐसा क्यों हो रहा है? Django के ORM का उपयोग करके उसी तालिका में रिकॉर्ड के बीच जटिल संबंधों का संदर्भ देने का उचित तरीका क्या है?

संपादित करें: मुझे यह useful snippet मिला है जिसमें कस्टम एसक्यूएल शामिल है .extra() ताकि यह मॉडल प्रबंधक के अंदर उपयोग योग्य हो।

उत्तर

10

मुझे लगता है कि आप भूल रहे हैं का चयन पैरामीटर (अतिरिक्त विधि के लिए)

यह काम करने के लिए लगता है:

qs = Triple.objects.filter(subject="bob", predicate="knows").extra(
      select={'known': "t1.subject"}, 
      tables=['"triple_triple" AS "t1"'], 
      where=['''triple_triple.object=t1.subject 
        AND t1.predicate="has-a" AND t1.object="''']) 

qs.values("known") 
+0

धन्यवाद। अजीब है कि यह अतिरिक्त तालिका को बस छोड़ देगा क्योंकि इसे SELECT में संदर्भित नहीं किया गया था, क्योंकि यह क्वेरी को तोड़ता है जब दूसरी तालिका WHERE खंड में फ़िल्टर करने के लिए उपयोग की जाती है। संभावित बग? – Cerin

+0

@ सेरिन: मुझे नहीं लगता कि यह एक बग है, इसकी मेरी गंदा व्याख्या यह है कि आप कहां से अधिक स्थितियों का उपयोग करते हैं और लौटाए गए क्वेरीसेट में और कॉलम जोड़ने का चयन करते हैं। –

+0

@ टॉमासो: मेरा बिंदु ऐसा लगता है कि मैं एकाधिक टेबल का उपयोग नहीं कर सकता जब तक कि मैं प्रत्येक तालिका से कम से कम एक कॉलम नहीं चुनता। यह समझ में नहीं आता है, क्योंकि मैं हमेशा शामिल नहीं होना चाहूंगा या प्रत्येक तालिका से कॉलम चुनने की ज़रूरत नहीं है जिसे मैं शामिल करना चाहता हूं। यही कारण है कि मुझे लगता है कि यह या तो एक बग या खराब डिजाइन की सुविधा है। – Cerin

0

मैं एक ही मुद्दा जहां Django निकल जाता था (वापस कहते हैं -टिक्स) मेरे टेबल नामों के लिए, जिसका अर्थ है कि मैं मैन्युअल रूप से उपनाम नहीं जोड़ सकता; FROM खंड जिसके परिणामस्वरूप इस तरह दिखता है:

"mytable" AS T100

लेकिन एक ही समय में, Django आपके लिए अपने आप उपनाम यदि तालिका पहले ही उल्लेख किया है नहीं बनाएगा; इसके बजाए यह तालिकाओं को अनदेखा करता है और केवल WHERE खंडों पर जोड़ता है जैसे कि वे मूल सारणी को संदर्भित करते हैं।

Django 1.8 के लिए दस्तावेज़ पता चलता है कि .extra() आप के लिए अन्य नाम बना देगा:

https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.extra

लेकिन यह अपनी क्वेरी के लिए मामला हो प्रतीत नहीं होता है, संभवतः क्योंकि मूल तालिका हिस्सा है एक्स, वाई, जेड खंड से सरल के बजाय एक बाएं बाहरी जॉइन की।

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