Python 在ORM查询中使用原始SQL

Python 在ORM查询中使用原始SQL,python,sqlalchemy,Python,Sqlalchemy,是否可以使用您自己的原始SQL进行编辑或覆盖ORM生成的SQL?或者ORM应该足够灵活,可以构建我能想象的任何查询吗 具体来说,这里是我试图提出的查询,也许通过ORM构建并不太困难,尽管我看不到任何明显的构建路径。模型如下: class AllocationStatus(Base): STATUS_RESERVED = 1 STATUS_RELEASED = 2 STATUS_CHOICES = ( (STATUS_RESERVED, "Reserved

是否可以使用您自己的原始SQL进行编辑或覆盖ORM生成的SQL?或者ORM应该足够灵活,可以构建我能想象的任何查询吗

具体来说,这里是我试图提出的查询,也许通过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())
这个想法是,对于
分配\u ID
的给定外键ID,我想知道
分配\u状态中的最新记录

为了在原始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;
选择分配状态*
从分配状态
左连接分配\状态分配\状态2
在分配时\u状态.allocation\u id=分配\u状态2.allocation\u id
和分配\u status.id<分配\u status 2.id
其中分配_status2.id为空;

您可以通过先为模型添加别名,然后将该别名用作外部联接的第二个表来构建它。 以下假设您已经有一个绑定到工作引擎的会话:

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()
来自sqlalchemy.orm的
导入别名
从sqlalchemy导入和_
分配状态2=别名(AllocationStatus)
session.query(AllocationStatus)\
外部连接(分配状态2,
和(AllocationStatus.allocation_id==allocation_status 2.allocation_id,,
AllocationStatus.id<分配状态2.id))\
筛选器(分配\状态2.id.is\无)).all()

我希望这会有所帮助。

您可以先为模型添加别名,然后将该别名用作外部联接的第二个表来构建它。 以下假设您已经有一个绑定到工作引擎的会话:

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()
来自sqlalchemy.orm的
导入别名
从sqlalchemy导入和_
分配状态2=别名(AllocationStatus)
session.query(AllocationStatus)\
外部连接(分配状态2,
和(AllocationStatus.allocation_id==allocation_status 2.allocation_id,,
AllocationStatus.id<分配状态2.id))\
筛选器(分配\状态2.id.is\无)).all()

我希望这会有所帮助。

由@Abdou给出的答案是正确的选择,但您也可以使用以下方法运行文本SQL:

session.query(分配状态)\
from_语句(文本(“”)
选择分配状态*
从分配状态
左连接分配\状态分配\状态2
在分配时\u状态.allocation\u id=分配\u状态2.allocation\u id
和分配\u status.id<分配\u status 2.id
其中分配_status2.id为NULL;“”)\
全部()

请注意。

使用@Abdou的答案是正确的,但您也可以使用以下方法运行文本SQL:

session.query(分配状态)\
from_语句(文本(“”)
选择分配状态*
从分配状态
左连接分配\状态分配\状态2
在分配时\u状态.allocation\u id=分配\u状态2.allocation\u id
和分配\u status.id<分配\u status 2.id
其中分配_status2.id为NULL;“”)\
全部()
注意使用