我正在使用sqlAlchemy以编程方式查询具有复合外键的表.例如.:
@H_301_6@CREATE TABLE example ( id INT NOT NULL,date TIMESTAMP NOT NULL,data VARCHAR(128) PRIMARY KEY (id,date) )
我想拿一个值列表并获取行例如:
@H_301_6@interesting_data = ( (1,'2016-5-1'),(1,'2016-6-1'),(2,(3,) select( [example.c.id,example.c.date,example.c.data],).where(example.primary_key.in_(interesting_data)
如果每列都是独立的,我可以做到
@H_301_6@interesting_ids = [1,2,3] interesting_dates = ['2016-5-1','2016-6-1'] select( [example.c.id,).where( example.c.id.in_(interesting_ids) ).where( example.c.date.in_(interesting_dates) )
最佳答案
在where子句中使用list comprehension:
@H_301_6@from sqlalchemy import and_,or_,select stmt = select( [example.c.id,example.c.data] ).where(or_(and_(example.c.id==data[0],example.c.date==data[1]) for data in interesting_data))
但是,我注意到的另一个问题是您将日期列与字符串数据类型进行比较. interesting_data列表应该是
@H_301_6@import datetime as dt interesting_data = ( (1,dt.date(2016,5,1)),6,)
另请注意,可以创建基本语句,然后逐步向其添加子句,从而导致(希望)更好的易读性和代码重用.
因此,可以将上面的内容写成
@H_301_6@base_stmt = select([example.c.id,example.c.data]) wheres = or_(and_(example.c.id==data[0],example.c.date==data[1]) for data in interesting_data)) stmt = base_stmt.where(wheres)
@H_301_6@SELECT example.id,example.date,example.data FROM example WHERE example.id = :id_1 AND example.date = :date_1 OR example.id = :id_2 AND example.date = :date_2 OR example.id = :id_3 AND example.date = :date_3 OR example.id = :id_4 AND example.date = :date_4 OR example.id = :id_5 AND example.date = :date_5
注意:如果要像这样过滤很多行,那么创建临时表,从interesting_data向此临时表插入行,然后将内部连接插入此表可能更有效,而不是如图所示添加where子句以上.