Thanks Simon ! I got it working using the hack.
I'm not using the "mapper_configured" event because I need to add a "parent" attribute to the subclass of TreeNode, which should be done before the mapping. On Friday, February 17, 2017 at 6:21:57 PM UTC+8, Simon King wrote: > > On Fri, Feb 17, 2017 at 10:03 AM, <linl...@gmail.com <javascript:>> > wrote: > > I want to achieve something like this: > > > > Base = declarative_base() > > > > # the abstract base, no table generated for it > > class TreeNode(Base): > > __abstract__ = True > > parent = Column(ForeignKey('child_class_table.id'), nullable=False) > > > > def is_root(self): > > pass > > def get_parent(self): > > pass > > > > # more methods > > > > > > # the child, mapped to a table(in this case named 'discipline') > > class Discipline(TreeNode): > > __tablename__ = 'discipline' > > > > id = Column(Integer, primary_key=True) > > name = Column(Unicode(500), nullable=False) > > > > > > # a generated auxiliary table for the child(in this case named > > 'discipline_closure') > > class DisciplineClosure(Base): > > __tablename__ = 'discipline_closure' > > > > ancestor_id = Column(ForeignKey('discipline.id'), nullable=False) > > descendant_id = Column(ForeignKey('discipline.id'), nullable=False) > > depth = Column(Integer, nullable=False) > > > > Is this possible in SQLAlchemy? How to implement it ? > > Or is there an another way to implement my closure table ? > > > > My Django implementation Attached, but I wanna do it using SQLAlchemy. > > > > You could look at the versioned_history example, which creates history > tables for classes inheriting from a "Versioned" mixin: > > > http://docs.sqlalchemy.org/en/latest/orm/examples.html#module-examples.versioned_history > > > Here's the Versioned class: > > class Versioned(object): > @declared_attr > def __mapper_cls__(cls): > def map(cls, *arg, **kw): > mp = mapper(cls, *arg, **kw) > _history_mapper(mp) > return mp > return map > > Declarative accesses the __mapper_cls__ attribute when creating the > SQLAlchemy mapper for the class. The Versioned class uses that as a > hook to generate the second class. > > This is a bit of a hack (particularly since __mapper_cls__ seems to be > barely documented). It might be possible to do something similar using > ORM events, but I haven't tried it. You could investigate the > mapper_configured event: > > > http://docs.sqlalchemy.org/en/latest/orm/events.html#sqlalchemy.orm.events.MapperEvents.mapper_configured > > > The code would look something like: > > @event.listens_for(TreeNode, 'mapper_configured', propagate=True) > def receive_mapper_configured(mapper, class_): > # Create your Closure class here > > Hope that helps, > > Simon > -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.