2009-06-04 14 views
6

मैं SQLAlchemy निम्न रूप में एसक्यूएल उत्पन्न करने के लिए पैदा करने के लिए एक रास्ता खोजने के लिए कोशिश कर रहा हूँ:SQLAlchemy जटिल in_ खंड

 
select * from t where (a,b) in ((a1,b1),(a2,b2)); 

यह संभव है?

यदि नहीं, तो इसे अनुकरण करने के तरीके पर कोई सुझाव?

धन्यवाद कृपया!

उत्तर

3

ठीक है, ऊपर हाओ लिआन के लिए धन्यवाद, दर्दनाक समाधान अगर मैं एक कार्यात्मक के साथ आया था।

मान लें कि हम एक कथात्मक शैली मैप किया वर्ग, Clazz, और मिश्रित प्राथमिक कुंजी मूल्यों की tuples के एक list है, values (एक बेहतर (IMO) एसक्यूएल पीढ़ी शैली का उपयोग करने संपादित):

 
from sqlalchemy.sql.expression import text,bindparam 
... 
    def __gParams(self, f, vs, ts, bs): 
     for j,v in enumerate(vs): 
      key = f % (j+97) 
      bs.append(bindparam(key, value=v, type_=ts[j])) 
      yield ':%s' % key 

    def __gRows(self, ts, values, bs): 
     for i,vs in enumerate(values): 
      f = '%%c%d' % i 
      yield '(%s)' % ', '.join(self.__gParams(f, vs, ts, bs)) 

    def __gKeys(self, k, ts): 
     for c in k: 
      ts.append(c.type) 
      yield str(c) 

    def __makeSql(self,Clazz, values): 
     t = [] 
     b = [] 
     return text(
       '(%s) in (%s)' % (
        ', '.join(self.__gKeys(Clazz.__table__.primary_key,t)), 
        ', '.join(self.__gRows(t,values,b))), 
       bindparams=b) 

यह समाधान यौगिक या सरल प्राथमिक कुंजी के लिए काम करता है। हालांकि यह सामान्य प्राथमिक कुंजी के लिए शायद col.in_(keys) से थोड़ा धीमा है।

मुझे अभी भी ऐसा करने के बेहतर तरीकों के सुझावों में रुचि है, लेकिन इस तरह से अब काम कर रहा है और or_(and_(conditions)) तरीके से for key in keys: do_stuff(q.get(key)) तरीके से बेहतर प्रदर्शन करता है।

4

मानक चेतावनी: मैं बड़े और ट्विस्टी पारिस्थितिकी तंत्र में कोई विशेषज्ञ नहीं हूं जो स्क्लेक्लेमी है।

तो मान लें कि आपके पास stocks नामक एक सारणी है और session नाम का एक सत्र है। तब क्वेरी जैसे

x = "(stocks.person, stocks.number) IN ((100, 100), (200, 200))" 
session.query(stocks).filter(x).all() 

कुछ अंगूठे का एक अच्छा नियम है कि SQLAlchemy ऐसे filter पद्धति के रूप में सबसे अधिक स्थानों पर जहां ऐसा लगता है कि यह उत्पन्न हो सकता है, में कच्चे एसक्यूएल स्वीकार करेगा होगा।

हालांकि, मुझे विश्वास नहीं है कि कच्चे एसक्यूएल के बिना ऐसा करने का कोई तरीका है। in_ ऑपरेटर को आपके उदाहरण में कॉलम के tuples के बजाय केवल Column पर परिभाषित किया गया है। (साथ ही, यह केवल एसक्यूएल कार्यान्वयन पर काम करता है जो इसका समर्थन करता है - विशेष रूप से SQLite इसे चलाने वाले त्वरित उदाहरणों में इसका समर्थन नहीं करता है। आपको बाएं टुपल में कॉलम को अर्हता प्राप्त करने में भी सावधान रहना होगा, खासकर अगर स्क्लाक्लेमी ने कृपया इसे संभाला टेबल निर्माण।)

+0

मुझे लगता है कि से डर लगता था - जब यौगिक प्राथमिक कुंजी के साथ काम कर रहा है कि यह एक बहुत उपयोगी निर्माण होगा। जवाब के लिए धन्यवाद! – lostlogic

17

उपयोग tuple_ में tuple_ construct देखें:

keys = [(a1, b1), (a2, b2)] 
session.query(T).filter(tuple_(T.a, T.b).in_(keys)).all() 

http://docs.sqlalchemy.org/en/latest/core/sqlelement.html#sqlalchemy.sql.expression.tuple_

+0

चेतावनी चेतावनी (एसक्लाल्चेमी डॉक्टर से): समग्र में निर्माण सभी बैकएंड द्वारा समर्थित नहीं है, और वर्तमान में पोस्टग्रेएसक्यूएल और माईएसक्यूएल पर काम करने के लिए जाना जाता है, लेकिन SQLite नहीं। असमर्थित बैकएंड डीबीएपीआईआरर के उप-वर्ग को बढ़ाएंगे जब ऐसी अभिव्यक्ति लागू की जाती है। – Bryan