我曾经在classmethod
__declare_last__
中注册sqlalchemy事件。
我的代码如下所示:
@classmethod
def __declare_last__(cls):
@event.listens_for(cls, 'after_udpate')
def receive_after_update(mapper, conn, target):
...
在我升级到SQLAlchemy 1.0之前,该方法一直有效,直到我未调用此hook
并因此未注册我的事件。
我已经阅读了有关__declare_last__
的1.0文档,但没有发现任何相关内容。
python大神给出的解决方案
在SQLAlchemy1.0.4的源代码中搜索__declare_last__
之后,我找到了找到并注册__declare_last__
和__declare_first__
的地方。
def _setup_declared_events(self):
if _get_immediate_cls_attr(self.cls, '__declare_last__'):
@event.listens_for(mapper, "after_configured")
def after_configured():
self.cls.__declare_last__()
if _get_immediate_cls_attr(self.cls, '__declare_first__'):
@event.listens_for(mapper, "before_configured")
def before_configured():
self.cls.__declare_first__()
然后,我使用pdb
逐步遍历此方法,发现_get_immediate_cls_attr(self.cls, '__declare_last__')
对于继承了该hook方法的类返回None
。
所以我跳到_get_immediate_cls_attr
的定义,其中包含一个可以解决我的问题的文档字符串:
def _get_immediate_cls_attr(cls, attrname, strict=False):
"""return an attribute of the class that is either present directly
on the class, e.g. not on a superclass, or is from a superclass but
this superclass is a mixin, that is, not a descendant of
the declarative base.
This is used to detect attributes that indicate something about
a mapped class independently from any mapped classes that it may
inherit from.
因此,我只是添加了一个mixin
类,将__declare_last__
移至其中,并使原始基类继承了mixin
,现在终于再次调用了__declare_last__
。