2017-04-27 18 views
2

select语句列SQL是有办法让SQLAlchemy中生成一个自定义列,它是与当前行相关子查询的查询:使用ORM API生成与子查询中使用的SQLAlchemy

SELECT 
tab1.id, 
tab1.col1, 
..., 
(
    SELECT count(1) FROM tab2 
    WHERE tab2.tab1_id = tab1.id 
    GROUP BY tab2.col1 
) as cnt 
FROM tab1 
WHERE ... 
LIMIT 100 

session.query(Tab1, ?(subquery for additional column)?).filter(...).limit(100) 

我使用PostgreSQL 9.3和旧版本的SQLAlchemy 0.9.8

+1

您需要一个标量子查询。 ['Query.label()'](http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.label)或'Query.as_scalar()'将得到你那个。另请阅读[标量选择](http://docs.sqlalchemy.org/en/latest/core/tutorial.html#scalar-selects)以及关联Core文档中的子查询。 –

回答

2

如果您经常需要和/或计数是您的Tab1模型的组成部分,则应该使用混合属性,如其他答案中所述。如果在另一方面,你需要这只是一个单一的查询,那么你可以只创建一个使用Query.label(),或Query.as_scalar()标量子查询:

count_stmt = session.query(func.count(1)).\ 
    filter(Tab2.tab1_id == Tab1.id).\ 
    group_by(Tab2.col1).\ 
    label('cnt') 

session.query(Tab1, count_stmt).filter(...).limit(100) 

子查询将automatically correlate什么可以从封闭查询。

1

你可以这样做的,但它在一个完全不同的方式,你是如何写它的工作原理。您可以创建依赖于以TAB2的关系(假设tab2.tab1_id是一个外键,它应该是TAB1的属性

你的模型是这样的:

class Parent(Base): 
    __tablename__ = 'parent' 
    id = Column(Integer, primary_key=True) 
    children = relationship("Child") 

class Child(Base): 
    __tablename__ = 'child' 
    id = Column(Integer, primary_key=True) 
    parent_id = Column(Integer, ForeignKey('parent.id')) 

the docs on relationships

那么你可以添加类似

@hybrid_property 
def number_of_children(self): 
    if self.children: 
     return len(self.children) 
    return 0 

@number_of_children.expression 
def number_of_children(cls): 
    return (select([func.count(Child.id)]) 
      .where(Child.cover_id == cls.id)) 

到父模式,按this answermore docs

完成此操作后,您可以对此属性进行过滤,这与其他任何基于列的相同。