在stackoverflow上发现一个应用案例,在此转载一下。
class Entry(AbstractConcreteBase, db.Model): """Base Class of Entry.""" id = db.Column(db.Integer, primary_key=True, nullable=False) created = db.Column(db.DateTime, nullable=False) post_id = declared_attr(lambda c: db.Column(db.ForeignKey("post.id"))) post = declared_attr(lambda c: db.relationship("Post", lazy="joined")) @declared_attr def __tablename__(cls): return cls.__name__.lower() @declared_attr def __mapper_args__(cls): # configurate subclasses about concrete table inheritance return {'polymorphic_identity': cls.__name__, 'concrete': True} if cls.__name__ != "Entry" else {} class TextEntry(Entry): """Text and Article Entry.""" text = db.deferred(db.Column(db.Text, nullable=False)) class PhotoEntry(Entry): """Photo Entry.""" path = db.deferred(db.Column(db.String(256), nullable=False))
以上Entry是一个基类,没有对应的数据库表,TextEntry和PhotoEntry均继承自Entry。
class Post(db.Model): """An Post.""" id = db.Column(db.Integer, primary_key=True, nullable=False) description = db.Column(db.Unicode(140), nullable=False) entries = db.relationship(Entry, lazy="dynamic")
理想情况应该是post的entries可以包含不同的Entry,如
>>Post.entries.query.all() [<PhotoEntry 'Title' created by tonyseek>, <PhotoEntry 'TITLE 2' created by tonyseek>, <PhotoEntry 'Title 3' created by tonyseek>, <PhotoEntry 'Title 4' created by tonyseek>, <TextEntry 'Title' created by tonyseek>]
幸运的是AbstractConcreteBase提供了__delcare_last__
可以用来解决这些问题,代码如下:
class Post(db.Model): id = db.Column(db.Integer, primary_key=True, nullable=False) description = db.Column(db.Unicode(140), nullable=False) @classmethod def __declare_last__(cls): cls.entries = db.relationship(Entry, viewonly=True) def attach_entries(self, entries): """Attach Entries To This Post. Example: >>> post = Post("An Interesting News", "Wow !!!") >>> text_entry = TextEntry(*t_args) >>> photo_entry = PhotoEntry(*p_args) >>> post.attach_entries([text_entry, photo_entry]) >>> len(post.entries) 2 >>> db.session.commit() >>> """ for entry in entries: self.entries.append(entry) entry.post = self db.session.add(entry)
原文地址在这里:http://stackoverflow.com/questions/9223630/sqlalchemy-polymorphic-relationship-with-concrete-inheritance