अजीब SQLAlchemy त्रुटि संदेश: TypeError: 'dict' ऑब्जेक्ट इंडेक्सिंग का समर्थन नहीं करता है


145

मैं SqlAlchemy का उपयोग करते हुए पीजी डेटाबेस से डेटा लाने के लिए हैंड क्राफ्टेड एसक्यूएल का उपयोग कर रहा हूं। मैं एक क्वेरी की कोशिश कर रहा हूं जिसमें एसक्यूएल जैसे ऑपरेटर '%' है और जो लूप के माध्यम से SqlAlcjhemy को फेंक देता है:

sql = """
       SELECT DISTINCT u.name from user u
        INNER JOIN city c ON u.city_id = c.id
        WHERE c.designation=upper('fantasy') 
        AND c.id IN (select id from ref_geog where short_name LIKE '%opt')
      """

# The last line in the above statement throws the error mentioned in the title. 
# However if the last line is change to:
# AND c.id IN (select id from ref_geog where short_name = 'helloopt')
# the script runs correctly.
#
# I also tried double escaping the '%' i.e. using '%%' instead - that generated the same error as previously.

connectDb()
res = executeSql(sql)
print res
closeDbConnection()

कोई भी जानता है कि इस भ्रामक त्रुटि संदेश के कारण क्या है और मैं इसे कैसे ठीक कर सकता हूं?

[[संपादित करें]]

किसी से भी पूछने से पहले, ऊपर दिए गए कार्यों के बारे में कुछ विशेष या फैंसी नहीं है। उदाहरण के लिए, कार्य निष्पादित (एसक्यूएल) con.execute (sql) को लागू करता है और परिणाम देता है। चर कनवर्टर डेटाबेस के लिए पहले से स्थापित कनेक्शन है।


क्या आप का कोड पोस्ट कर सकते हैं executeSql(...)? और भी, क्या आप वास्तव RETURNING *में SELECTबयान में हैं?
वैन

@ इवान मुझे याद आया। SQL में कोई 'RETURNING *' नहीं है जो समस्या पैदा कर रहा है। मैं सवाल सही करूंगा।
होम्युनकुलस रेटिकुल्ली

1
क्या यह उत्तर [ stackoverflow.com/questions/3944276/… मददगार है?
वैन

2
@ इवन: धन्यवाद! हाँ यह करता है। मुझे '%' के बजाय '%%' का उपयोग करना था। बयान को अब सही ढंग से निष्पादित किया गया है।
होम्युनकुलस रेटिकुल्ली

3
महान। कृपया एक संक्षिप्त उत्तर पोस्ट करें (और इसे स्वीकार करें) जो पूर्णता के लिए आपके लिए काम करता है।
वैन

जवाबों:


227

आपको %%इसका उपयोग करने के लिए देना होगा %क्योंकि %अजगर में स्ट्रिंग प्रारूपण के रूप में उपयोग किया जाता है, इसलिए जब आप एकल को %यह मान लेते हैं कि आप इसके साथ कुछ मूल्य को प्रतिस्थापित करने जा रहे हैं।

तो जब आप %क्वेरी स्ट्रिंग के साथ सिंगल को डबल जगह देना चाहते हैं %


27
काश वे उस त्रुटि संदेश को अपडेट करते, हर बार जब मैं इसे प्राप्त करता हूं तो मैं इस पृष्ठ पर उतरता हूं और जवाब देता
हूं

86

SQLAlchemy में text()रैपिंग टेक्स्ट के लिए एक फ़ंक्शन है जो आपके लिए SQL से सही ढंग से बचने के लिए प्रकट होता है।

अर्थात

res = executeSql(sqlalchemy.text(sql))

आपके लिए काम करना चाहिए और आपको मैनुअल भागने से बचाना चाहिए।


13
यह चयनित उत्तर होना चाहिए। इसने मेरे मामले में समस्या हल कर दी।
गनी सिमसेक

1
ध्यान दें कि यह टिप्पणियों से बचता नहीं है, लेकिन अन्यथा एक शानदार समाधान है।
ClimbsRocks 21

मेरे लिए काम किया, और हमारे सभी प्रश्नों को दोहरे% के साथ बदलने की तुलना में लागू करना आसान था
फिलिप ओगर


4

ऐसा लगता है कि आपकी समस्या इस बग से संबंधित हो सकती है ।

किस स्थिति में, आपको वर्कअराउंड के रूप में ट्रिपल-एस्केप करना चाहिए।


2

मुझे एक और मामला मिला जब यह त्रुटि दिखाई देती है:

c.execute("SELECT * FROM t WHERE a = %s")

दूसरे शब्दों में, यदि आप %sक्वेरी में पैरामीटर ( ) प्रदान करते हैं , लेकिन आप क्वेरी परम जोड़ना चाहते हैं। इस स्थिति में त्रुटि संदेश बहुत भ्रामक है।


1

एक और नोट- आपको %टिप्पणियों में भी वर्णों से बचना (या हटाना) चाहिए । दुर्भाग्य से, sqlalchemy.text(query_string)टिप्पणियों में प्रतिशत संकेतों से बच नहीं जाता है।


1

अपनी समस्या को हल करने का एक और तरीका, यदि आप %पात्रों से बचना या उपयोग नहीं करना चाहते हैं, तो sqlalchemy.text()एक नियमित अभिव्यक्ति का उपयोग करना है।

के बजाय:

select id from ref_geog where short_name LIKE '%opt'

प्रयास करें (केस-संवेदी मिलान के लिए):

select id from ref_geog where short_name ~ 'opt$' 

या (केस-असंवेदनशील के लिए):

select id from ref_geog where short_name ~* 'opt$'

दोनों LIKEऔर regex पैटर्न मिलान पर प्रलेखन में शामिल हैं ।

ध्यान दें कि:

LIKE पैटर्न के विपरीत, एक नियमित अभिव्यक्ति को स्ट्रिंग के भीतर कहीं भी मिलान करने की अनुमति दी जाती है, जब तक कि नियमित अभिव्यक्ति को स्ट्रिंग की शुरुआत या अंत में स्पष्ट रूप से लंगर नहीं डाला जाता है।

एक लंगर के लिए, आप $स्ट्रिंग के अंत (या ^शुरुआत के लिए) का उपयोग कर सकते हैं ।


0

यह मामले से भी हो सकता है - मामले में SQL पर पारित होने वाले मापदंडों को DICT फॉर्मेट में घोषित किया जाता है और LIST या TUPPLE के रूप में SQL में हेरफेर किया जा रहा है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.