SQLAlchemy に次の形式のクエリを生成させる方法を見つけようとしています。
select * from t where (a,b) in ((a1,b1),(a2,b2));
これは可能ですか?
そうでない場合、それをエミュレートする方法に関する提案はありますか?
SQLAlchemy に次の形式のクエリを生成させる方法を見つけようとしています。
select * from t where (a,b) in ((a1,b1),(a2,b2));
これは可能ですか?
そうでない場合、それをエミュレートする方法に関する提案はありますか?
使用tuple_
:
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_
さて、上記の Hao Lian のおかげで、私は痛みを伴う場合でも機能的な解決策を思いつきました。
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): キー = f % (j+97) bs.append(bindparam(key, value=v, type_=ts[j])) yield ':%s' % キー def __gRows(自己、ts、値、bs): for i,vs in enumerate(values): f = '%%c%d' % i yield '(%s)' % ', '.join(self.__gParams(f, vs, ts, bs)) def __gKeys(自己、k、ts): k の c の場合: ts.append(c.type) 利回り str(c) def __makeSql(self,Clazz, values): t = [] b = [] リターンテキスト( '(%罪)' % ( ', '.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 0.6のtuple_ コンストラクトを参照してください。