I have a declarative base class Entity
which defines the column name
as polymorphic, e.g.
class Entity(DeclarativeBase):
name = Column('name', String(40))
__mapper_args__ = {'polymorphic_on':name}
In subclasses, I could now say
class Experiment(Entity):
__mapper_args__ = {'polymorphic_identity': "experiment"}
and be done. However, I would like to ease the creation of subclasses for the users of my library and therefore make the following possible:
poly_id = "exp"
inside the class or maybe a class decorator.I tried to get this done using metaclasses (only the second part):
from sqlalchemy.ext.declarative import DeclarativeMeta
class Meta(type):
def __init__(cls, classname, bases, dict_):
dict_["__mapper_args__"] = {'polymorphic_identity': classname}
return super(Meta, cls).__init__(classname, bases, dict_)
class CombinedMeta(Meta, DeclarativeMeta):
pass
class Experiment(Entity):
__metaclass__ = CombinedMeta
so that, in my opinion, my Meta
should set the name before calling the DeclarativeMeta
but it does not seem to work. So either the DeclarativeMeta
which supposedly sets the polymorphic name never sees the change because I messed up the MRO or what I’m doing is plain wrong anyway. What would I need to change or is there even something like this in SQLAlchemy already?
Shame on me but the problem could easily be solved by not using the dict_
but by setting the attribute directly on cls
.
class Meta(DeclarativeMeta):
def __init__(cls, *args, **kw):
if getattr(cls, '_decl_class_registry', None) is None:
return # they use this in the docs, so maybe its not a bad idea
cls.__mapper_args__ = {'polymorphic_identity': cls.__name__}
return super(Meta, cls).__init__(*args, **kw)
class Experiment(Entity):
__metaclass__ = Meta
Recent sqlalchemy docs show ways of using mixin classes for such purposes (I'm not sure whether it only works in versions >= 0.6 or if it is only better documented now)
http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative/mixins.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With