2017-08-28 67 views
0

是否可以使用自己的原始SQL编辑或覆盖ORM生成的SQL?或者ORM是否有足够的灵活性来构建几乎可以想象的任何查询?在ORM查询中使用原始SQL

具体来说,这是我试图做的查询,也许它不是很难通过ORM构建,尽管我无法看到任何明显的构建路径。这里的模型:

class AllocationStatus(Base): 

    STATUS_RESERVED = 1 
    STATUS_RELEASED = 2 
    STATUS_CHOICES = (
     (STATUS_RESERVED, "Reserved"), 
     (STATUS_RELEASED, "Released"), 
    ) 

    __tablename__ = 'allocation_status' 

    id = Column(Integer, primary_key=True) 
    allocation_id = Column(Integer, ForeignKey('allocation.id')) 
    allocation = relationship('Allocation') 
    status = Column(Integer()) 

的想法是,为allocation_id给定的外键ID,我想知道在allocation_status的最新记录。

为了在原始的SQL语句来实现这一点,下面的查询是我的目标为:

SELECT allocation_status.* 
FROM allocation_status 
LEFT JOIN allocation_status allocation_status2 
    ON allocation_status.allocation_id = allocation_status2.allocation_id 
    AND allocation_status.id < allocation_status2.id 
WHERE allocation_status2.id IS NULL; 

回答

3

可以通过先混叠模型,然后使用该别名作为第二个表来构建它外连接。 以下假定你已经有一个绑定到工作引擎会话:

from sqlalchemy.orm import aliased 
from sqlalchemy import and_ 


allocation_status2 = aliased(AllocationStatus) 
session.query(AllocationStatus).\ 
    outerjoin(allocation_status2, 
       and_(AllocationStatus.allocation_id == allocation_status2.allocation_id, 
        AllocationStatus.id < allocation_status2.id)).\ 
    filter(allocation_status2.id.is_(None)).all() 

我希望这有助于。

+0

很好用!谢谢。 – DanH

2

通过@Abdou答案是要走的正确方法,但你也可以使用Query.from_statement()运行文本SQL:

session.query(AllocationStatus).\ 
    from_statement(text(""" 
     SELECT allocation_status.* 
     FROM allocation_status 
     LEFT JOIN allocation_status allocation_status2 
       ON allocation_status.allocation_id = allocation_status2.allocation_id 
       AND allocation_status.id < allocation_status2.id 
     WHERE allocation_status2.id IS NULL;""")).\ 
    all() 

注意使用text()