使用SQLAlchemy上的别名连接两次相同的表

and*_*nik 9 python sqlalchemy

我试图将以下查询移植到SQLAlchemy:

SELECT u.username, GROUP_CONCAT(DISTINCT userS.name)
FROM Skills AS filterS 
INNER JOIN UserSkills AS ufs ON filterS.id = ufs.skill_id
INNER JOIN Users AS u ON ufs.user_id = u.id
INNER JOIN UserSkills AS us ON u.id = us.user_id
INNER JOIN Skills AS userS ON us.skill_id = userS.id
WHERE filterS.name IN ('C#', 'SQL')
GROUP BY u.id;
Run Code Online (Sandbox Code Playgroud)

我不明白如何在SQLAlchemy中实现AS语句.这是我目前拥有的:

# User class has attribute skills, that points to class UserSkill
# UserSkill class has attribute skill, that points to class Skill
db.session.query(User.id, User.username, func.group_concat(Skill.name).label('skills')).\
   join(User.skills).\
   join(UserSkill.skill).filter(Skill.id.in_(skillIds)).\
   order_by(desc(func.count(Skill.id))).\
   group_by(User.id).all()
Run Code Online (Sandbox Code Playgroud)

请帮忙.

and*_*nik 10

我想通了.以下是我的Flask应用程序中使用的类:

class User(Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = Column(db.String(80), unique=True, nullable=False)
    skills = db.relationship('UserSkill')

class Skill(Model):
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = Column(db.String(80))

class UserSkill(Model):
    status = db.Column(db.Enum(SkillStatus))
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True)
    skill_id = db.Column(db.Integer, db.ForeignKey('skills.id'), primary_key=True)
    skill = db.relationship("Skill")
Run Code Online (Sandbox Code Playgroud)

所以,实际的代码看起来像这样:

userSkillF = aliased(UserSkill)
userSkillI = aliased(UserSkill)
skillF = aliased(Skill)
skillI = aliased(Skill)

db.session.query(User.id, User.username,\
         func.group_concat(func.distinct(skillF.name)).label('skills'),\
         func.group_concat(func.distinct(skillI.name)).label('other_skills')).\
    join(userSkillF, User.skills).\
    join(userSkillI, User.skills).\
    join(skillF, userSkillF.skill).filter(skillF.id.in_(skillIds)).\
    join(skillI, userSkillI.skill).\
    group_by(User.id).all()
Run Code Online (Sandbox Code Playgroud)

非常感谢IljaEverilä,对SqlAlchemy文档的全新了解让我明白aliased了.


Ram*_*amy 6

我们也可以在没有关系的情况下进行连接。明确提及加入的条件。

例子

    from sqlalchemy.orm import aliased
    user1 = aliased(UserSkill)
    user2 = aliased(UserSkill)
    query_result = db.session.query(func.distinct(User.id).label('user_id'),User.username).\
        join(user1,User.id==user1.user_id).\
        join(user2,user2.id==User.id).\
        filter(user1.user_id==id).all()
Run Code Online (Sandbox Code Playgroud)