2012-11-02 11 views
12

मैं प्रदर्शन कारणsqlalchemy में एक कस्टम क्वेरी में पैरामीटर को सूची कैसे जोड़ सकता हूं?

sql_tmpl = """delete from Data where id_data in (:iddata) """ 
params = { 
        'iddata':[1, 2,3 4], 
        } 
# session is a session object from sqlalchemy 
self.session.execute(text(sql_tmpl), params)  

हालांकि मैं एक अपवाद

NotSupportedError: (NotSupportedError) ('Python type list not supported. param=1', 'HY097') 

कोई वैकल्पिक हल है कि मुझे 'में' के पैरामीटर के लिए एक सूची बाध्य करने के लिए अनुमति दे सकते हैं है मिल गया खंड के लिए इस एसक्यूएल उपयोग कर रहा हूँ ?

+0

मूल्यों एक में करने के लिए पारित कर दिया अभी भी असतत, एसक्यूएल में प्रदान की गई मान होते हैं, इसलिए एसक्यूएल अलग-अलग बाध्य पैरामीटर को शामिल करने के लिए अभी भी स्टेटमेंट बनाया जाना चाहिए। यदि आप शाब्दिक एसक्यूएल का उपयोग कर रहे हैं तो आपको "iddata1,: iddata2, .." आदि का एक स्ट्रिंग concatenation करना होगा। नीचे गैरी का जवाब सही है। – zzzeek

उत्तर

8
एक पुराने सवाल का

न्यू जवाब क्योंकि ऐसा लगता है अंतर्निहित कार्यक्षमता के कुछ के बाद से यह सवाल/स्वीकार किए जाते हैं जवाब पहले पोस्ट किए गए बदल की तरह है (जैसा कि @ गैरी के जवाब में @vicvicvic से उल्लेख है, लेकिन मुझे लगता है यह बेहतर दृश्यता के लिए एक जवाब होना चाहिए)।

psycopg2 अब type adaptation का समर्थन करता है, जो अन्य चीजों के अलावा, क्वेरी में एक पैरामीटरयुक्त मान में सूची को पास करने की क्षमता देता है। यह SQLAlchemy में भी काम करता है, कम से कम कच्चे-एसक्यूएल-एस्क्यू प्रश्नों के लिए पोस्टग्रेस्क्ल डेटाबेस (मुझे अन्य डेटाबेस प्रकारों तक पहुंच नहीं है, इसलिए मुझे नहीं पता कि sqlalchemy अन्य डेटाबेस के लिए इस सम्मेलन का सम्मान करेगा, लेकिन मेरा झुकाव उद्धरण आवश्यक यह है कि यह काम करेगा)।

some_ids = [1, 2, 3, 4] 
query = "SELECT * FROM my_table t WHERE t.id = ANY(:ids);" 
conn.execute(sqlalchemy.text(query), ids=some_ids) 
## runs just fine 

मैंने पाया कि sqlalchemy.text के आवरण कॉल के बिना, यह एक ProgrammingError: syntax error at or near ":" दे दी है।

2

जहां तक ​​मुझे पता है, एसक्यूएल इंजनों में से कोई भी सरणी पैरामीटर में गुजरने की अनुमति नहीं देता है। जिस तरह से sqlalchemy इसे संभालता है वह सरणी में प्रत्येक आइटम के लिए पैरामीटर में पास करना है।

>>> from sqlalchemy.sql import table, column 
>>> print(table('Data').delete(column('id_data').in_([5, 6, 7,]))) 
DELETE FROM "Data" WHERE id_data IN (:id_data_1, :id_data_2, :id_data_3) 

यदि आप sqlalchemy अभिव्यक्ति संरचनाओं का उपयोग नहीं करते हैं, तो आपको इसे मैन्युअल रूप से करने की आवश्यकता होगी।

+2

मुझे नहीं पता कि यह जवाब कब लिखा गया था, लेकिन अब 'psycopg2' एक [गुच्छा समेत जबरदस्ती का गुच्छा] का समर्थन करता है (http://initd.org/psycopg/docs/usage.html#python -types-अनुकूलन)। उदाहरण के लिए देखें [टुपल्स अनुकूलन] (http://initd.org/psycopg/docs/usage.html#tuples-adaptation)। दुर्भाग्यवश, ऐसा लगता है कि एसक्यूएल कीमिया अपने तर्क का उपयोग करता है ताकि यह सुविधा केवल psycopg2 का उपयोग कर उपलब्ध हो। – vicvicvic

2

माता-पिता के बिना प्रयास करें: iddata यह मेरे लिए काम कर रहा है।

sql_tmpl = """delete from Data where id_data in :iddata """ 
+1

ठीक काम करता है, लेकिन पैरामीटर एक ट्यूपल होना चाहिए। एक सूची के साथ काम नहीं करेगा। –

1

आप लूप का उपयोग करके एक खंड उत्पन्न कर सकते हैं और query.execute पैरामीटर में सूची को तोड़ने के लिए ** का उपयोग कर सकते हैं। यहाँ एक उदाहरण है: https://gist.github.com/pawl/555e5eecce77d4de0ada

0

dwanderson के उत्तर में जोड़ना: SQLAalchemy का उपयोग करके आप किसी भी प्रश्न में "कोई भी" फ़ंक्शन जोड़ने के लिए func विधि का उपयोग कर सकते हैं। यह मेरे लिए SQLAlchemy 1.0.9 और एक पोस्टग्रेस डीबी का उपयोग कर काम करता है।

जेनेरिक उदाहरण:

from sqlalchemy import func 

# some list 
id_list = [1, 2, 3] 

# assuming you have created a session 
query = session.query(Table.user_name, Table.user_id).\ 
    filter(Table.user_id == func.any(id_list)) 

# one way of running the query 
query.all() 

आप सत्यापित कर सकते हैं कि सूची में एक भी पैरामीटर के रूप में पारित हो जाता है (के रूप में सूची में वस्तु प्रति एक पैरामीटर के खिलाफ)।

print(query.statement) 

चयन user_id, user_name तालिका से कहां table.user_id = किसी भी (: any_1)

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