SQLAlchemy继承并返回适当的子类

时间:2014-09-09 00:32:53

标签: python-3.x sqlalchemy flask-sqlalchemy

对于背景,这是我正在使用Flask构建的个人项目的一部分,因此也是Flask-SQLAlchemy。艺术家有专辑的概念。会员有播放列表。专辑和播放列表都可以有曲目。对我来说,这听起来像是继承的教科书案例 - 专辑和播放列表都只是特定类型的轨道列表。逻辑有点复杂,因为我需要为每个单独的轨道列表维护单独的轨道定位标记;然而,这与我的实际问题相关。

class Tracklist(db.Model):
    __tablename__ = 'tracklists'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(128), index=True)
    type = db.Column(db.Unicode(16))
    tracks = db.relationship('TrackPosition', backref='tracklist')

    __mapper_args__ = {
        'polymorphic_on' : type,
        'with_polymorphic' : '*'
        }

class Album(Tracklist):
    __tablename__ = 'albums'

    id = db.Column(db.Integer, db.ForeignKey('tracklists.id'), primary_key=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('artists.id'), primary_key=True)

    __mapper_args_ = {
        'polymorphic_identity' : 'album',
        'inherit_condition' : (id == Tracklist.id)
        }

class Playlist(Tracklist):
    __tablename__ = 'playlists'

    id = db.Column(db.Integer, db.ForeignKey('tracklists.id'), primary_key=True)
    owner_id = db.Column(db.Integer, db.ForeignKey('members.id'), primary_key=True)

    __mapper_args_ = {
        'polymorphic_identity' : 'playlist',
        'inherit_condition' : (id == Tracklist.id)
        }

我在会员和艺术家模型上设置了专门引用播放列表和专辑的关系。它们按预期工作(如果有点麻烦,但我还没有使用任何关联代理),例如:

atdi = models.Artist(name='At the Drive-In')
atdi.albums.append(models.Album(name='Relationship of Command'))
arcarsenal = models.Track(name="Arcarsenal", artist=atdi)
atdi.albums[0].tracks.append(models.TrackPosition(track=arcarsenal, position=1))

但是当我问arcarsenal它属于哪个跟踪列表时,我不会回复专辑或播放列表类型。我找回了Tracklist类型。如果我问atdi它有哪些相册,我会收到相册类型。如果我创建一个带有播放列表的成员并向其添加arcarsenal,我会在通过会员时返回播放列表类型,但通过Track模型返回Tracklist。

我一直在梳理联接表继承的文档,在这里查看代码示例和问题;我觉得我正好想着解决这个问题,但我不能完全理解它,因为我已经看了很久了。

1 个答案:

答案 0 :(得分:0)

最后有人指出我在Album和Playlist模型mapper args上缺少一个下划线。 :/想象一下。