0

我有一个大致如下所示的 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'}

我想对具有特定艺术家的歌曲或视频进行一次查询;即,这两个查询在一个查询中(所有查询都应该是.order_by(Streamable.score)):

q1=Streamable.query.with_polymorphic(Video)
q1.join(Video.song, participation, Artist).filter(Artist.id==1)
q2=Streamable.query.with_polymorphic(Song)
q2.join(participation, Artist).filter(Artist.id==1)

这是我达到的最好的;它发出可怕的 SQL 并且总是产生空结果(不知道为什么):

p1=db.aliased(participation)
p2=db.aliased(participation)
a1=db.aliased(Artist)
a2=db.aliased(Artist)
q=Streamable.query.with_polymorphic((Video, Song))
q=q.join(p1, a1).join(Video.song, p2, a2)
q.filter(db.or_((a1.id==1), (a2.id==1))).order_by('score')

如果有的话,执行此查询的正确方法是什么(也许关系数据存储不是我工作的正确工具......)?

4

1 回答 1

1

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

q=q.outerjoin(p1, a1).outerjoin(Video.song, p2, a2)

我还将替换为order_by

q = q.order_by(Streamable.score)
于 2012-11-20T12:19:57.937 回答