Python SQLAlchemy:迭代返回多行的子查询
假设我有一个名为ItemMap的类,它是一个实际SQL Server数据库表item_map的SQLAlchemy表示 给定Python datetime变量d和字符串代码,下面的查询计算ItemMap.date列和d之间的datediff(以天为单位),按降序排序,然后返回ItemMap.code列条目等于code的前两行 例如,设置d=datetime.datetime2016,8,2,12,45和code='V',然后运行pd.DataFrameq.all返回: 这是正确的行为 我遇到的问题是,我看不到如何为在另一个表或视图或其他可选实体中定义的许多datetime元素顺序运行此逻辑 因此,例如,假设有另一个名为r的项表示某个数据库实体拥有一个datetime列,这样运行pd.DataFramesession.queryr.c.datetime.all的结果是 我希望按顺序为这些元素中的每一个运行上面q中封装的查询逻辑,并整理输出,以便获得:Python SQLAlchemy:迭代返回多行的子查询,python,sql-server,sqlalchemy,Python,Sql Server,Sqlalchemy,假设我有一个名为ItemMap的类,它是一个实际SQL Server数据库表item_map的SQLAlchemy表示 给定Python datetime变量d和字符串代码,下面的查询计算ItemMap.date列和d之间的datediff(以天为单位),按降序排序,然后返回ItemMap.code列条目等于code的前两行 例如,设置d=datetime.datetime2016,8,2,12,45和code='V',然后运行pd.DataFrameq.all返回: 这是正确的行为 我遇到的问
code date item
0 V 2016-08-02 V-1
1 V 2016-08-01 V-1
2 V 2016-08-04 V-2
3 V 2016-08-03 V-2
4 V 2016-08-09 V-3
5 V 2016-08-08 V-3
必须在服务器端执行此联合类型的操作。因此,我要寻找的是一个单一的SQLAlchemy操作,大致如下:
q = session.query(
ItemMap,
).filter(
func.datediff(text('day'), ItemMap.date, r.c.datetime) >= 0,
ItemMap.code==code,
).order_by(
ItemMap.date.desc(),
).limit(2)\
.iterate_over(r.c.datetime) # (not a real SQLAlchemy command)
请注意,在客户端对r的元素进行迭代,为每个元素形成一个单独的q,并通过union_进行排序,这些原则上都有效,但实际上,一旦元素数量超过某个上限,数据库API就会拒绝这些元素。在我的实际应用程序中,我需要为比这里提供的样式化示例多出许多数量级的数据运行此操作。为什么不使用SQL,它将在SQL Server端执行,也就是说,应该更高效,并使用以下命令读取结果:df=pd.read_SQL'select。。。从表格中加入。。。哪里order by…,conn,conn是create_engine返回的SQLAlchemy连接吗?@MaxU对于纯SQL解决方案没有问题,尽管我尝试过这样做,也很难看到它是如何工作的。这两种方法都可以,但我对SQLAlchemy方法特别感兴趣,因为这是我应用程序其余部分的实现方式。顺便说一句,在效率方面,由于SQLAlchemy只是构建和发布SQL,我不明白为什么纯SQL方法必然会带来比在第一个实例中在客户端构建SQL更高的效率。还是我遗漏了什么?
code date item
0 V 2016-08-02 V-1
1 V 2016-08-01 V-1
datetime
0 2016-08-02 12:45:00
1 2016-08-04 12:45:00
2 2016-08-09 12:45:00
code date item
0 V 2016-08-02 V-1
1 V 2016-08-01 V-1
2 V 2016-08-04 V-2
3 V 2016-08-03 V-2
4 V 2016-08-09 V-3
5 V 2016-08-08 V-3
q = session.query(
ItemMap,
).filter(
func.datediff(text('day'), ItemMap.date, r.c.datetime) >= 0,
ItemMap.code==code,
).order_by(
ItemMap.date.desc(),
).limit(2)\
.iterate_over(r.c.datetime) # (not a real SQLAlchemy command)