I would like to use Mixin to make a base class for MPTT trees, just as an example
class MPTT(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
id = db.Column(db.Integer, primary_key = True)
level = db.Column(db.Integer, nullable = False)
lft = db.Column(db.Integer, nullable = False)
rgt = db.Column(db.Integer, nullable = False)
@declared_attr
def parent_id(cls):
return db.Column(db.Integer, db.ForeignKey(cls.id))
@declared_attr
def num_children(cls):
mptt2 = aliased(cls)
return column_property(select([func.count(cls.id)]).where(cls.parent_id == mptt2.id))
And then use it like:
class Node(MPTT, Base):
__tablename__ = 'node'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(150), nullable = False)
urlname = db.Column(db.String(150), nullable = False)
is_visible = db.Column(db.Boolean, default = True)
def __repr__(self):
return '%r (%r - %r)' % (self.name, self.lft, self.rgt)
def __init__(self, name, urlname, parent = None):
super(Node, self).__init__(parent)
self.urlname = urlname
However I have problem using aliased in the mixin getting an error:
File "./app/ext_mptt/models.py", line 24, in ordernum
mptt2 = aliased(cls)
File "./venv/lib/python2.7/site-packages/sqlalchemy/orm/util.py", line 385, in aliased
return AliasedClass(element, alias=alias, name=name, adapt_on_names=adapt_on_names)
File "./venv/lib/python2.7/site-packages/sqlalchemy/orm/util.py", line 298, in __init__
self.__mapper = _class_to_mapper(cls)
File "./venv/lib/python2.7/site-packages/sqlalchemy/orm/util.py", line 673, in _class_to_mapper
raise exc.UnmappedClassError(class_or_mapper)
sqlalchemy.orm.exc.UnmappedClassError: Class 'app.cms.models.Node' is not mapped
I thought the num_children method should be called when Node is mapped. Will be grateful for any hints!