2017-04-27 35 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

完成此操作後,您可以對此屬性進行過濾,這與其他任何基於列的相同。