Событие sqlalchemy class_instrument не срабатывает - PullRequest
0 голосов
/ 12 марта 2019

Я не могу понять, как вызвать событие class_instrument.Может быть, это ожидаемо, я не могу точно сказать из документов, что события инструмента должны срабатывать только для пользовательских настроек приборов.

Но attribute_instrument делает, так что я решил спросить.

Документы здесь https://docs.sqlalchemy.org/en/latest/orm/events.html#module-sqlalchemy.orm.instrumentation.

from sqlalchemy import *
from sqlalchemy.event import listens_for
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

if __name__ == "__main__":
  class A(Base):
    __tablename__ = 'a'

    id = Column(Integer, primary_key=True)
    data = Column(String)


  @listens_for(A, 'class_instrument')
  def on_class_instrument(mapper, cls):
    """"""
    print('class_instrument')
    cls.data.info['cls'] = True


  @listens_for(A, 'attribute_instrument')
  def on_attribute_instrument(cls, key, inst):
    """"""
    print('attribute_instrument', cls)
    cls.data.info['attr'] = True


  a = A()
  assert A.data.info['attr']
  # Succeeds above, but fails here
  assert A.data.info['cls']

1 Ответ

1 голос
/ 12 марта 2019

С объявлением класс инструментируется во время конструирования, поэтому ваш обработчик событий связан слишком поздно.Сопоставители, с другой стороны, конфигурируются лениво в первый раз, когда они необходимы, поэтому атрибуты инструментируются при первом использовании A.

При просмотре документации вы должны связать своих слушателей с вашим классом Base.Для прослушивателей событий инструментария по умолчанию установлено значение propagate=True, поэтому вы будете получать события инструментария для подклассов Base:

from sqlalchemy import *
from sqlalchemy.event import listens_for
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

if __name__ == "__main__":
  @listens_for(Base, 'class_instrument')
  def on_class_instrument(cls):
    """"""
    print('class_instrument')
    cls.data.info['cls'] = True

  @listens_for(Base, 'attribute_instrument')
  def on_attribute_instrument(cls, key, inst):
    """"""
    print('attribute_instrument', cls)
    cls.data.info['attr'] = True

  class A(Base):
    __tablename__ = 'a'

    id = Column(Integer, primary_key=True)
    data = Column(String)    

  a = A()
  assert A.data.info['attr']
  # Succeeds
  assert A.data.info['cls']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...