SQLAlchemy JOIN vs Adjacency List

时间:2015-11-24 15:38:08

标签: python sql join sqlalchemy

考虑以下模型:

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)

1 个答案:

答案 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))