我有一个声明性基类Entity
,它将列name
定义为多态,例如。
class Entity(DeclarativeBase):
name = Column('name', String(40))
__mapper_args__ = {'polymorphic_on':name}
在子类中,我现在可以说
class Experiment(Entity):
__mapper_args__ = {'polymorphic_identity': "experiment"}
完成。但是,我想为我的库用户简化子类的创建,因此可以实现以下目标:
poly_id = "exp"
,也可能是类装饰器。我尝试使用元类(仅第二部分)完成此操作:
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
因此,在我看来,我的Meta
应该在调用DeclarativeMeta
之前设置名称,但它似乎不起作用。因此,假定设置多态名称的DeclarativeMeta
从未看到变化,因为我弄乱了MRO或者我正在做的事情无论如何都是完全错误的。我需要改变什么,或者SQLAlchemy中是否还有这样的东西?
答案 0 :(得分:7)
对我感到羞耻,但问题可以通过不使用dict_
轻松解决,但可以直接在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
答案 1 :(得分:1)
最近的sqlalchemy文档显示了将mixin类用于此类目的的方法(我不确定它是否仅适用于版本> = 0.6或者现在只能更好地记录)
http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/declarative/mixins.html