С объявлением класс инструментируется во время конструирования, поэтому ваш обработчик событий связан слишком поздно.Сопоставители, с другой стороны, конфигурируются лениво в первый раз, когда они необходимы, поэтому атрибуты инструментируются при первом использовании 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']