考虑以下模型:
installRelease
假设我想在给定对象A的情况下访问C ID。这是正确的(也是最快的)方法吗?或者我应该去JOIN查询还是其他SQL魔术?
class A(db.Model):
id = db.Column(db.Integer, primary_key=True)
bs = db.relationship('B', backref='A')
class B(db.Model):
id = db.Column(db.Integer, primary_key=True)
cs = db.relationship('C', backref='A')
class C(db.Model):
id = db.Column(db.Integer, primary_key=True)
答案 0 :(得分:0)
*编辑* 在查询中更改每个A的C!
您可以创建一个简单的查询来解决您的问题,如下所示:
q = session.query(C).join(B).join(A)
c_list = q.all()
c_list将包含与连接条件匹配的每个对象。 如果您想查看生成的查询,那很简单:
print(str(q))
SELECT c_table.c_id AS c_table_c_id,c_table.id AS c_table_id FROM c_table JOIN b_table ON b_table.id = c_table.c_id JOIN a_table ON a_table.id = b_table.a_id
*编辑* 这种方法比迭代python对象更有效:你只有一个由DB解析的查询,如果你遍历你的对象,SQLAlchemy可能需要触发一些触发器来从数据库中加载剩余的对象read {{3 }}
接下来是我用来复制案例的脚本:
from sqlalchemy import Column, create_engine, ForeignKey
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.types import Integer
from sqlalchemy.ext.declarative import declarative_base
model = declarative_base()
class A(model):
__tablename__ = 'a_table'
id = Column(Integer, primary_key=True)
bs = relationship('B', backref='A')
class B(model):
__tablename__ = 'b_table'
a_id = Column(Integer, ForeignKey('a_table.id'))
id = Column(Integer, primary_key=True)
cs = relationship('C', backref='B')
class C(model):
__tablename__ = 'c_table'
c_id = Column(Integer, ForeignKey('b_table.id'))
id = Column(Integer, primary_key=True)
engine = create_engine('postgresql+psycopg2://playground:playground@localhost:5432/playground')
session_factory = sessionmaker(bind=engine)
session = session_factory()
model.metadata.create_all(engine)
a = A()
b = B(A=a)
c = C(B=b)
session.add(a)
session.commit()
q = session.query(C).filter(C.id == 1)
c = q.first()
print(c.B.A.id)
q = session.query(A).filter(A.id == 1)
a = q.first()
c_id = [c.id for a in a.bs for c in b.cs]
q = session.query(C).join(B).join(A)
c_list = q.all()
print(str(q))