我試圖找到一種方法,使SQLAlchemy中生成以下形式的SQL:SQLAlchemy的複雜IN_條款
select * from t where (a,b) in ((a1,b1),(a2,b2));
這可能嗎?
如果不是,有什麼建議在模擬它的方法上?
謝謝親切!
我試圖找到一種方法,使SQLAlchemy中生成以下形式的SQL:SQLAlchemy的複雜IN_條款
select * from t where (a,b) in ((a1,b1),(a2,b2));
這可能嗎?
如果不是,有什麼建議在模擬它的方法上?
謝謝親切!
好吧,多虧了上面的郝連,我想出了一個功能如果痛苦的解決方案。
假設我們有一個聲明式映射類,Clazz
,和化合物的主鍵值的元組的list
,values
(編輯,以使用更好的(IMO)SQL生成式):
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))
方式。
標準警告:我並不是SQLAlchemy這個龐大而曲折的生態系統的專家。
假設您有一個名爲stocks
的表和一個名爲session
的會話。那麼查詢也只是像
x = "(stocks.person, stocks.number) IN ((100, 100), (200, 200))"
session.query(stocks).filter(x).all()
一個好的經驗法則是,SQLAlchemy的將接受在它看起來可能會產生它最多的地方,如filter
方法原始的SQL。
但是,我不相信有沒有辦法做到這一點沒有原始的SQL。 in_
運算符似乎只在Column
s上定義,而不是像你在例子中那樣的列的元組。 (另外,這隻適用於支持它的SQL實現 - 特別是SQLite在我運行的快速示例中似乎不支持這一點。您還必須小心地限定左元組中的列,特別是如果SQLAlchemy友好地處理表格創作。)
看到SQLAlchemy的0.6
使用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_
警告 警告(來自sqlalchemy doc):所有後端都不支持組合IN構造,目前已知可在PostgreSQL和MySQL上使用,但不支持SQLite。當這種表達式被調用時,不支持的後端將引發DBAPIError的子類。 – Bryan 2017-11-17 16:37:44
我害怕的是 - 用複合主鍵打交道時,它會是一個非常有用的結構。感謝你的回答! – lostlogic 2009-06-04 02:51:44