以SQLAlchemy格式表达SQL Join和多对多过滤器

时间:2018-11-16 09:15:42

标签: python sqlalchemy many-to-many flask-sqlalchemy

我正在尝试学习SQLAlchemy最佳实践,以便a)做我需要做的事,b)以最有效的方式做事。

我目前有3个表,用于定义clubperson之间的多对多关系。

class Club(db.Model)
   __tablename__ = 'club'
   id = db.Column(db.Integer, primary_key=True)
   type = db.Column(db.String)

class Person(db.Model)
   __tablename__ = 'person'
   id = db.Column(db.Integer, primary_key=True)

club_person_assoc = Table('club_person_ass', db.Model.metadata,
    Column('club_id', db.Integer, db.ForeignKey('club.id')),
    Column('person_id', db.Integer, db.ForeignKey('person.id'))
)

返回的一种好方法是:所有clubs是特定person (person.id==1)的成员,并且取决于俱乐部类型(club.type='sports') < / em>

在SQL中,我可以将语句直接表示为:

SELECT *
  FROM (
    SELECT *
      FROM club
      WHERE club.type = 'sports'
  ) AS lef
INNER JOIN (
    SELECT *
      FROM club_person_assoc
      WHERE club_person_assoc.person_id = 1
    ) AS rig
  ON lef.id = rig.club_id;

我可以通过以下方式使用python列表理解来欺骗它:

class Person(db.Model)
       ...
       clubs = db.relationship('Club', secondary=club_person_assoc)

# later using list comprehension
filtered = [club for club in person_x.clubs if club.type == 'sports']

但是,上面的内容当然比本地数据库查询人为且缓慢。

如果您对文档之外的其他位置有很好的建议,请以一种更具指导性的风格进行评论。

1 个答案:

答案 0 :(得分:0)

我没有教程建议,但是进行列表理解与以最有效的方式进行列表恰恰相反。

执行此操作的方式类似于:

Session().query(Club.Id).join(Person).filter(Club.type == "sports").filter(Person.id == 1).all()