Python 从子对象查询项目
我有一个flaskpython应用程序,它有一组通过外键链接在一起的相关表。我希望能够从一个表返回与远程表相关的记录的聚合列表。然而,我很难理解sqlalchemy是如何通过对象关系实现这一点的 例如,我希望将三个对象(挑战和徽章)与两个表(talent_挑战和徽章)连接起来,以便能够查询与特定挑战相关的所有徽章。在SQL中,这类似于:Python 从子对象查询项目,python,flask,sqlalchemy,Python,Flask,Sqlalchemy,我有一个flaskpython应用程序,它有一组通过外键链接在一起的相关表。我希望能够从一个表返回与远程表相关的记录的聚合列表。然而,我很难理解sqlalchemy是如何通过对象关系实现这一点的 例如,我希望将三个对象(挑战和徽章)与两个表(talent_挑战和徽章)连接起来,以便能够查询与特定挑战相关的所有徽章。在SQL中,这类似于: SELECT b.id, b.name FROM badge b INNER JOIN talent_challenge tc ON tc.talent_id
SELECT b.id, b.name
FROM badge b
INNER JOIN talent_challenge tc ON tc.talent_id = b.talent_id
WHERE tc.challenge_id = 21
在这种情况下不需要“人才”和“挑战”表,因为我只需要关系中的人才和挑战ID(在“人才挑战”中)。所有有趣的细节都在徽章表中
我能够使用sqlalchemy通过以下方式从挑战中获得相关天赋:
talents = db.relationship('TalentModel', secondary='talent_challenge')
然后我可以为每一个天赋引用天赋。徽章
,以获得与我最初挑战相关的徽章。但是,可能存在冗余,并且此徽章列表不包含在单个对象中
这三种型号的精简版为:
class TalentModel(db.Model):
__tablename__ = 'talent'
# Identity
id = db.Column(db.Integer, primary_key=True)
# Relationships
challenges = db.relationship('ChallengeModel', secondary='talent_challenge',)
# badges (derived as backref from BadgeModel)
class ChallengeModel(db.Model):
__tablename__ = 'challenge'
# Identity
id = db.Column(db.Integer, primary_key=True)
member_id = db.Column(db.Integer, db.ForeignKey('member.id'))
# Relationships
talents = db.relationship('TalentModel', secondary='talent_challenge', order_by='desc(TalentModel.created_at)')
class BadgeModel(db.Model):
__tablename__ = 'badge'
# Identity
id = db.Column(db.Integer, primary_key=True)
talent_id = db.Column(db.Integer, db.ForeignKey('talent.id'))
# Parents
talent = db.relationship('TalentModel', foreign_keys=[talent_id], backref="badges")
我还有一个关联表“人才挑战”的模型:
class TalentChallengeModel(db.Model):
__tablename__ = 'talent_challenge'
# Identity
id = db.Column(db.Integer, primary_key=True)
talent_id = db.Column(db.Integer, db.ForeignKey('talent.id'))
challenge_id = db.Column(db.Integer, db.ForeignKey('challenge.id'))
# Parents
talent = db.relationship('TalentModel', uselist=False, foreign_keys=[talent_id])
challenge = db.relationship('ChallengeModel', uselist=False, foreign_keys=[challenge_id])
我想更好地理解sqlalchemy(或者特别是sqlalchemy),以允许我从挑战对象构建此徽章列表。BadgeModel的db.session.query
是我唯一的选择吗
2015年1月23日更新:
我的项目中的拦截器已通过以下方法解决:
@property
def badges(self):
from app.models.sift import BadgeModel
from app.models.relationships.talent import TalentChallengeModel
the_badges = BadgeModel.query\
.join(TalentChallengeModel, TalentChallengeModel.talent_id==BadgeModel.talent_id)\
.filter(TalentChallengeModel.challenge_id==self.id)\
.all()
return the_badges
将查询包装到函数中,解决了我遇到的名称BadgeModel
未定义以及无法在模型中导入的问题。@属性
装饰器允许我稍后在视图中将其作为挑战.徽章
引用
然而,我仍然有兴趣了解如何作为一种关系做到这一点。其他地方的一些搜索让我相信这会奏效:
badges = db.relationship('BadgeModel',
secondary="join(BadgeModel, TalentChallengeModel, BadgeModel.talent_id == TalentChallengeModel.talent_id)",
secondaryjoin="remote([id]) == foreign(TalentChallengeModel.challenge_id)",
primaryjoin="BadgeModel.talent_id == foreign(TalentChallengeModel.talent_id)",
viewonly=True,
)
由于我的应用程序环境中存在其他未解决的问题,我无法完全测试这一点(例如,在我的站点中添加此代码),但我想知道这是否是正确的语法,以及与函数解决方案中的查询相比,这是否有任何缺点