【问题标题】:SQLAlchemy filtering Children in one-to-many relationshipsSQLAlchemy过滤一对多关系中的孩子
【发布时间】:2019-08-29 04:48:20
【问题描述】:

我已将我的模型定义为:

class Row(Base):
    __tablename__ = "row"
    id = Column(Integer, primary_key=True)
    key = Column(String(32))
    value = Column(String(32))
    status = Column(Boolean, default=True)
    parent_id = Column(Integer, ForeignKey("table.id"))

class Table(Base):
    __tablename__ = "table"
    id = Column(Integer, primary_key=True)
    name = Column(String(32), nullable=False, unique=True)
    rows=relationship("Row", cascade="all, delete-orphan")

要从数据库中读取表,我可以简单地查询表,它会加载表所拥有的所有行。但是,如果我想通过 'status == True' 过滤行,它就不起作用。我知道这不是一个有效的查询,但我想做类似的事情:

session.query(Table).filter(Table.name == name, Table.row.status == True).one()

由于我无法使上述查询工作,我想出了一个新的解决方案,首先查询表而不加载任何行,然后使用 Id 使用过滤器查询 Rows,然后将结果分配给 Table 对象:

table_res = session.query(Table).option(noload('rows')).filter(Table.name == 'test').one()
rows_res = session.query(Row).filter(Row.parent_id == 1, Row.status == True)

table_res.rows = rows_res

但我相信必须有更好的方法一次性做到这一点。有什么建议吗?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    你可以试试这个 SQLAlchemy 查询:

    from sqlalchemy.orm import contains_eager
    
    result = session.query(Table)\
        .options(contains_eager(Table.rows))\
        .join(Row)\
        .filter(Table.name == 'abc', Row.status == True).one()
    
    print(result)
    print(result.rows)
    

    这会导致这个 SQL:

    SELECT "row".id AS row_id, 
        "row"."key" AS row_key, 
        "row".value AS row_value, 
        "row".status AS row_status, 
        "row".parent_id AS row_parent_id, 
        "table".id AS table_id, 
        "table".name AS table_name
    FROM "table" JOIN "row" ON "table".id = "row".parent_id
    WHERE "table".name = ? 
        AND "row".status = 1
    

    它执行连接,但还包括contains_eager 选项以在一个查询中执行此操作。否则,将在第二个查询中按需获取行(您也可以在关系中指定这一点,但这是解决它的一种方法)。

    【讨论】:

      猜你喜欢
      • 2014-03-12
      • 2021-08-14
      • 2012-02-08
      • 1970-01-01
      • 2014-05-19
      • 2021-12-17
      • 2012-11-11
      • 1970-01-01
      • 2018-05-03
      相关资源
      最近更新 更多