首页 > 解决方案 > 以 SQLAlchemy 格式表达 SQL 联接和多对多过滤器

问题描述

我正在尝试学习 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'))
)

什么是返回的好方法:特定成员的所有成员,以俱乐部类型为条件clubsperson (person.id==1)(club.type='sports')

在 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']

但是上面的内容当然比原生数据库查询感觉做作和慢。

如果您对除了文档之外的学习这些东西的好位置有任何建议,我将不胜感激以更教程的方式发表评论。

标签: pythonsqlalchemymany-to-manyflask-sqlalchemy

解决方案


我没有教程推荐,但做列表理解与以最有效的方式做完全相反。

这样做的方式是这样的:

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

推荐阅读