如何在SQLAlchemy 1.0中使用`__declare_last__`? - python

我曾经在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__