跨多个表的 SQLAlchemy 关系 [英] SQLAlchemy relationships across multiple tables

查看:18
本文介绍了跨多个表的 SQLAlchemy 关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个跨越 3 个表的关系,但我不太清楚语法.

I'm trying to create a relationship that spans across 3 tables but I can't quite figure out the syntax.

我有 3 个表 TableATableBTableC,我试图建模的关系是:

I have 3 tables TableA, TableB and TableC and the relationship I'm trying to model is:

TableA.my_relationship = relationship(
    'TableC',
    primaryjoin='and_(TableA.fk == TableB.pk, TableB.fk == TableC.pk)',
    viewonly=True
)

以便在 TableA 的实例上,我可以执行 instance_of_a.my_relationship 来获取与 instance_of_a 间接关联的 TableC 记录

so that on an instance of TableA I can do instance_of_a.my_relationship to get the TableC record that's indirectly associated with instance_of_a

推荐答案

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class A(Base):
    __tablename__ = 'a'

    id = Column(Integer, primary_key=True)
    b_id = Column(Integer, ForeignKey('b.id'))

    # method one - put everything into primaryjoin.
    # will work for simple lazy loads but for eager loads the ORM
    # will fail to build up the FROM to correctly include B
    cs = relationship("C",
                # C.id is "foreign" because there can be many C.ids for one A.id
                # B.id is "remote", it sort of means "this is where the stuff
                # starts that's not directly part of the A side"
                primaryjoin="and_(A.b_id == remote(B.id), foreign(C.id) == B.c_id)",
                viewonly=True)

    # method two - split out the middle table into "secondary".
    # note 'b' is the table name in metadata.
    # this method will work better, as the ORM can also handle 
    # eager loading with this one.
    c_via_secondary = relationship("C", secondary="b",
                        primaryjoin="A.b_id == B.id", secondaryjoin="C.id == B.c_id",
                        viewonly=True)
class B(Base):
    __tablename__ = 'b'

    id = Column(Integer, primary_key=True)
    c_id = Column(Integer, ForeignKey('c.id'))

class C(Base):
    __tablename__ = 'c'
    id = Column(Integer, primary_key=True)

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

sess = Session(e)

sess.add(C(id=1))
sess.flush()
sess.add(B(id=1, c_id=1))
sess.flush()
sess.add(A(b_id=1))
sess.flush()

a1 = sess.query(A).first()
print(a1.cs)

print(a1.c_via_secondary)

这篇关于跨多个表的 SQLAlchemy 关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆