SQLAlchemy:迭代返回多行的子查询

时间:2016-11-18 12:42:30

标签: python sql-server sqlalchemy

假设我有一个名为ItemMap的类 - 一个名为item_map的实际SQL-Server数据库表的SQLAlchemy表示。

class ItemMap(Model):
    __tablename__ = 'item_map'
    code = Column(String, primary_key=True)
    date = Column(DateTime, primary_key=True)
    item = Column(String)

给定Python日期时间变量d和字符串code,以下查询计算ItemMap.date列和d之间的天数,按降序排序,然后返回前两行(ItemMap.code列条目等于code)。

q = session.query(
    ItemMap,
).filter(
    func.datediff(text('day'), ItemMap.date, d) >= 0,
    ItemMap.code==code,       
).order_by(
    ItemMap.date.desc(),
).limit(2)

例如,设置d = datetime.datetime(2016,8,2,12,45)code='V',然后运行pd.DataFrame(q.all())会返回:

   code       date  item
0     V 2016-08-02   V-1
1     V 2016-08-01   V-1

这是正确的行为。

我遇到的问题是我无法看到如何按顺序为另一个表(或视图或其他可选实体)中定义的多个日期时间元素运行此逻辑。

因此,例如,假设有另一个名为r的项目,表示拥有datetime列的某个数据库实体,以便运行pd.DataFrame(session.query(r.c.datetime).all())的结果为

              datetime
0  2016-08-02 12:45:00
1  2016-08-04 12:45:00
2  2016-08-09 12:45:00

我想按顺序为每个元素运行上面q封装的查询逻辑,并整理输出,以便我们获得:

   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_all进行整理原则上有效,但实际上数据库API会拒绝该数字元素通过一些上限阈值。在我的实际应用程序中,我需要运行此数据的数量比此处提供的程式化示例多出几个数量级。

0 个答案:

没有答案