【问题标题】:Sqlalchemy creating group to group relationshipSqlalchemy 创建组对组关系
【发布时间】:2023-01-18 05:15:37
【问题描述】:

我有以下模型,其中我的两个模型共享一个 outside_id 到我无权访问的某个表,但它们是通过该表连接的。所以他们不是传统的多对多关系。我找到的唯一解决方案是创建一个主键为 outside_id 的表,并用它来连接这两个关系。

它增加了很多复杂性,因为我唯一需要的是能够在 A 中急切地从 B 加载数据并在我将其转储到 json 时访问它。有更简单的方法吗?

class B(model):
    id = Column(Integer(), primary_key=True, nullable=False)
    outside_id = Column(String())

class A(model):
    id = Column(Integer(), primary_key=True, nullable=False)
    outside_id = Column(String())

    relationship(
        "B",
        foreign_keys=[outside_id],
        primaryjoin="A.outside_id==B.outside_id",
        viewonly=True,
    )

【问题讨论】:

    标签: python sql postgresql sqlalchemy


    【解决方案1】:

    静态关系

    您可以使用 foreignremote 指定 primaryjoin 中的关系键。

    from sqlalchemy.orm import foreign, remote, joinedload
    
    class A(Base):
        __tablename__ = 'a_table'
        id = Column(Integer, primary_key=True)
        name = Column(String)
        outside_id = Column(Integer)
    
        b = relationship('B', primaryjoin="foreign(A.outside_id) == remote(B.outside_id)", viewonly=True)
    
    class B(Base):
        __tablename__ = 'b_table'
        id = Column(Integer, primary_key=True)
        name = Column(String)
        outside_id = Column(Integer)
    
    with Session(engine) as session:
       for a in session.scalars(select(A).options(joinedload(A.b))):
            print (a.id, a.outside_id, a.b.id if a.b else None)
    
    

    即席查询

    您也可以只在两个 outside_id 列上使用带有常规 outerjoin 的即席查询。

    with Session(engine) as session:
        
        results = []
        for a, b in session.execute(select(A, B).outerjoin(B, A.outside_id == B.outside_id)):
            results.append({
                'id': a.id,
                'name': a.name,
                'b': {
                    'id': b.id,
                    'name': b.name,
                } if b else None
            })
    

    【讨论】:

    • 这是使用sqlalchemy 1.4
    猜你喜欢
    • 1970-01-01
    • 2016-03-31
    • 2019-01-12
    • 1970-01-01
    • 2016-04-06
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多