Sqlalchemy 查询按多对多关系筛选的多个联接继承表

Sqlalchemy 查询按多对多关系筛选的多个联接继承表,sqlalchemy,flask-sqlalchemy,Sqlalchemy,Flask Sqlalchemy,我有一个SQLAlchemy方案,大致如下: participation = db.Table('participation', db.Column('artist_id', db.Integer, db.ForeignKey('artist.id'), primary_key=True), db.Column('song_id', db.Integer, db.ForeignKey('song.id'),

我有一个SQLAlchemy方案,大致如下:

participation = db.Table('participation',
        db.Column('artist_id', db.Integer, db.ForeignKey('artist.id'),
                  primary_key=True),
        db.Column('song_id', db.Integer, db.ForeignKey('song.id'),
                  primary_key=True),
)

class Streamable(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    kind = db.Column(db.String(10), nullable=False)
    score = db.Column(db.Integer, nullable=False)
    __mapper_args__ = {'polymorphic_on': kind}

class Artist(Streamable):
    id = db.Column(db.Integer, db.ForeignKey('streamable.id'), primary_key=True)
    name = db.Column(db.Unicode(128), nullable=False)
    __mapper_args__ = {'polymorphic_identity': 'artist'}

class Song(Streamable):
    id = db.Column(db.Integer, db.ForeignKey('streamable.id'), primary_key=True)
    name = db.Column(db.Unicode(128), nullable=False)
    artists = db.relationship("Artist", secondary=participation,
                              backref=db.backref('songs'))
    __mapper_args__ = {'polymorphic_identity': 'song'}

class Video(Streamable):
    id = db.Column(db.Integer, db.ForeignKey('streamable.id'), primary_key=True)
    song_id = db.Column(db.Integer, db.ForeignKey('song.id'), nullable=False)
    song = db.relationship('Song', backref=db.backref('videos', lazy='dynamic'),
                           primaryjoin="Song.id==Video.song_id")
    __mapper_args__ = {'polymorphic_identity': 'video'}
我想对有特定艺术家的歌曲或视频进行单一查询;i、 例如,在一个查询中包含这两个查询(所有查询应为
.order\u by(Streamable.score)
):

这是我达到的最好成绩;它发出可怕的SQL并总是产生空结果(不确定原因):


如果有的话,正确的查询方法是什么(可能关系数据存储不是我工作的合适工具…?

您的查询基本上是正确的。我认为将
join
更改为
outerjoin
应该可以解决这个问题:

q=q.outerjoin(p1, a1).outerjoin(Video.song, p2, a2)
我还将把订单替换为:

q = q.order_by(Streamable.score)

切换到outerjoin会使查询返回歌曲,但不会返回视频。仅按id==1的艺术家查询视频是可行的。奇怪的是,我的示例代码找到了这两个。。。可能是因为您的示例代码使用的是
a2.id==2
而不是
a2.id==1
?这种打字错误确实令人尴尬,但并非如此。即使我把它修好了,我仍然只能收到歌曲。我再次验证了我的单独查询(我原始问题中的中间代码块)确实返回了艺术家1的视频和艺术家1的歌曲。此外,我还编辑了原始问题以删除打字错误(
a2.id==1
),以免混淆人们。如果有帮助的话,我愿意分享我在pg_dump的方案。。。还有其他想法吗?好的。请在上检查代码。如果你运行脚本,它会返回一个视频和一首歌曲…你真是太全面了,非常感谢!我仍然不知道为什么,但当我在玩弄答案并试图理解错误所在时,我重新创建了我的数据库方案,并根据我拥有的样本数据重新创建了数据,问题就消失了。我想我的方案或数据可能有问题,但肯定是
outerjoin
s造成了重要的区别。再次感谢!
q=q.outerjoin(p1, a1).outerjoin(Video.song, p2, a2)
q = q.order_by(Streamable.score)