2009-03-03 16 views
19
class dbview(models.Model): 
    # field definitions omitted for brevity 
    class Meta: 
     db_table = 'read_only_view' 

def main(request): 
    result = dbview.objects.all() 

एक अपवाद पकड़ा जबकि प्रतिपादन के साथ देखने: (1054, "अज्ञात स्तंभ '। Read_only_view आईडी' 'क्षेत्र सूची' में")Django: क्वैरी केवल पढ़ने के लिए कोई प्राथमिक कुंजी

है कोई प्राथमिक कुंजी मैं दृश्य में देख सकता हूं। क्या आसपास कोई काम है?

टिप्पणी:
मेरे पास Django के साथ उपयोग करने के दृश्य पर कोई नियंत्रण नहीं है। MySQL ब्राउज़र कॉलम दिखाता है लेकिन कोई प्राथमिक कुंजी नहीं।

उत्तर

17

जब आप कहते हैं कि 'मैं दृश्य मैं Django के साथ तक पहुँचने हूँ पर कोई नियंत्रण नहीं। MySQL ब्राउज़र कॉलम दिखाता है लेकिन कोई प्राथमिक कुंजी नहीं। '

मुझे लगता है कि आपका मतलब है कि यह एक विरासत तालिका है और आपको कॉलम जोड़ने या बदलने की अनुमति नहीं है?

यदि ऐसा है और वास्तव में प्राथमिक कुंजी नहीं है (यहां तक ​​कि एक स्ट्रिंग या गैर-int कॉलम *) तो तालिका बहुत अच्छी तरह से स्थापित नहीं की गई है और प्रदर्शन अच्छी तरह से खराब हो सकता है।

हालांकि इससे कोई फर्क नहीं पड़ता। आपको केवल एक कॉलम चाहिए जो हर पंक्ति के लिए अद्वितीय होने की गारंटी है। अपने मॉडल में 'primary_key = True' होने के लिए सेट करें और Django खुश होंगे।

  • एक अन्य संभावना है जो समस्याग्रस्त होगी। यदि कोई स्तंभ नहीं है जो अद्वितीय होने की गारंटी है तो तालिका समग्र प्राथमिक कुंजी का उपयोग कर सकती है। यही है - यह निर्दिष्ट कर रहा है कि एक साथ किए गए दो कॉलम एक अद्वितीय प्राथमिक कुंजी प्रदान करेंगे। यह पूरी तरह से वैध संबंधपरक मॉडलिंग है लेकिन दुर्भाग्य से Django द्वारा असमर्थित। उस स्थिति में आप कच्चे एसक्यूएल के अलावा ज्यादा कुछ नहीं कर सकते हैं जब तक कि आप एक और कॉलम नहीं जोड़ सकते।
+0

आपको बहुत बहुत धन्यवाद, यह वास्तव में वास्तव में सहायक है! – dmi

+0

बहुत उपयोगी। जोड़ने के लिए एक बात; यदि प्राथमिक कुंजी के लिए आप जिस कॉलम का उपयोग करना चाहते हैं वह एक चार्ज प्रकार है, तो यह 255 वर्णों से अधिक नहीं हो सकता है। –

+6

यह वास्तव में प्रश्न को संबोधित नहीं करता है, जो एक डीबी व्यू से संबंधित है, न कि एक टेबल। आपने django के लिए अपने क्षेत्र में से एक को पीके के रूप में निर्दिष्ट किया है, चाहे वह है या नहीं। आप इससे दूर हो सकते हैं क्योंकि ओआरएम के माध्यम से संबंध में कोई भी सम्मिलित/अपडेट नहीं होगा। [डेविड एस का जवाब] देखें (http://stackoverflow.com/a/11594959/519015) और इस तकनीक के बारे में और अधिक के लिए मेरी टिप्पणी। –

1

वहाँ एक स्वत: जनरेट id क्षेत्र जब आप syncdb भाग गया (अगर कोई प्राथमिक कुंजी अपने मॉडल में परिभाषित किया गया है, तो आप के लिए एक Django AutoField से जोड़ दिया जाएगा) किया जाना चाहिए था।

यह त्रुटि का अर्थ है कि Django id फ़ील्ड के लिए अपना डेटाबेस पूछ रहा है, लेकिन कोई भी मौजूद नहीं है। क्या आप django manage.py dbshell और फिर DESCRIBE read_only_view; चला सकते हैं और परिणाम पोस्ट कर सकते हैं? यह डेटाबेस में मौजूद सभी कॉलम दिखाएगा।

वैकल्पिक रूप से, क्या आप उस मॉडल परिभाषा को शामिल कर सकते हैं जिसे आपने छोड़ा था? (और पुष्टि करें कि आप बदल नहीं किया है मॉडल परिभाषा के बाद से आप syncdb भाग गया?)

+0

धन्यवाद, मुझे शुरुआत में इसे और स्पष्ट करना चाहिए था। कृपया अद्यतन देखें। – dmi

+0

मैं जिस पंक्ति को आप एक्सेस कर रहे हैं उसे देखने के लिए नहीं कह रहा हूं, मैं बस अपनी मॉडल परिभाषा देखना चाहता हूं (एक ही चीज़ नहीं)। – obeattie

+0

मॉडल परिभाषाएं इस तरह हैं: text = models.CharField() हालांकि, मैं 'primary_key = True' वाले फ़ील्ड को परिभाषित नहीं कर सकता क्योंकि दृश्य में प्राथमिक कुंजी प्रतीत नहीं होती है। – dmi

3

यदि वाकई कोई प्राथमिक कुंजी ध्यान में रखते हुए है, तो इसका कोई समाधान नहीं है।

Django requires each model to have exactly one field primary_key=True.

+0

धन्यवाद! यदि मैं दृश्य में प्राथमिक कुंजी नहीं देख पा रहा हूं तो इसका मतलब है कि कोई प्राथमिक कुंजी नहीं है ...? मान लीजिए कि मैं सिर्फ कच्चे एसक्यूएल पर वापस आऊंगा। – dmi

+0

जरूरी नहीं है। नीचे मेरी टिप्पणी देखें। –

12

मेरे पास यह समस्या हर समय है। मेरे पास एक दृश्य है कि मैं बदलना नहीं चाहता या नहीं बदल सकता, लेकिन मैं एक समग्र पृष्ठ (शायद व्यवस्थापक अनुभाग में) प्रदर्शित करने के लिए एक पृष्ठ चाहता हूं। मैं तो बस बचाने के लिए और एक NotImplementedError बढ़ा ओवरराइड:

def save(self, **kwargs): 
     raise NotImplementedError() 

(हालांकि यह शायद ज्यादातर मामलों में की जरूरत नहीं है, लेकिन यह मुझे थोड़ा बेहतर महसूस करता है)

मैं भी मेटा में झूठी करने में कामयाब सेट कक्षा।

class Meta: 
     managed = False 

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

मेरे लिए ठीक काम करने लगता है। यदि इस तकनीक के साथ कोई समस्या है तो मैं कमेंट कर रहा हूं।

+2

आप केवल गैर-अद्वितीय फ़ील्ड को केवल पढ़ने के लिए प्राथमिक कुंजी के रूप में टैग कर सकते हैं, लेकिन इसमें 'queryset.distinct()। Count() 'और उदाहरण तुलना जैसी चीजों के लिए ramifications है। उत्तरार्द्ध के लिए एक समाधान के रूप में, आप मॉडल पर '__eq __()' को फिर से परिभाषित कर सकते हैं। –

+0

यदि आप आईडी चाहते हैं तो दृश्य में आप कुछ कर सकते हैं 'row_number() 'फ़ंक्शन (कम से कम PostgreSQL में) का उपयोग करें। 'AS +, आईडी के रूप में पंक्ति (संख्या) (ऑर्डर द्वारा फील्ड एएससी) चुनें – Bobort

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