2016-01-13 54 views
2

我正在使用SQLAlchemy并试图将事件添加到我的代码中。虽然一切正常,事件是而不是被触发。这里是我的简化代码:SQLAlchemy事件不起作用

from sqlalchemy import Column, String 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker 
from sqlalchemy import event 

alchemy_base = declarative_base() 

class Person(alchemy_base): 
    __tablename__ = 'my_table' 
    name = Column(String, primary_key=True) 

@event.listens_for(Person, "before_insert") 
def before_insert(mapper, connection, instance): 
    print("before_insert", mapper, connection, instance) 

engine = create_engine('sqlite:///:memory:', echo=True) 
alchemy_base.metadata.create_all(engine) 
session_maker = sessionmaker(bind=engine) 
session = session_maker() 

insert_dicts = [{'name': "ami"}, {'name': "beni"}] 
engine.execute(Person.__table__.insert(), insert_dicts) 
session.commit() 

功能before_insert不会被调用,虽然值输入到数据库。

我在Mac OS上使用python 2.7.10,SQLAlchemy 1.0.10。

+0

这看起来很适合我。当你最初设置事件时,你确定你传递了'mapper,connection,instance'的正确值吗? –

+0

@ Jeff-Widman:映射器,连接,实例是'before_insert'的参数,我没有通过它们,当'before_insert'被调用时(但它没有被调用),它们应该有有效值。设置事件应该由'@ event.listens_for'完成。 –

+0

你说得对,我的不好。我想知道它与你如何插入有关吗?也许使用'__table __。insert()'API绕过事件系统?您是否尝试过使用SQLAlchemy Core的官方API调用来插入Person? –

回答

3

before_insert是一个ORM事件。您正在使用SQLAlchemy Core而不是ORM。这工作。

>>> p = Person(name='Ami') 
>>> session.add(p) 
>>> session.commit() 
2016-01-13 23:37:42,887 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 
('before_insert', <Mapper at 0x1059e4dd0; Person>, <sqlalchemy.engine.base.Connection object at 0x105a2e990>, <__main__.Person object at 0x105a2e790>) 
2016-01-13 23:37:42,888 INFO sqlalchemy.engine.base.Engine INSERT INTO my_table (name) VALUES (?) 
2016-01-13 23:37:42,888 INFO sqlalchemy.engine.base.Engine ('Ami',) 
2016-01-13 23:37:42,888 INFO sqlalchemy.engine.base.Engine COMMIT 
+0

你是正确的这些听众不适用于所有层面的sqlalchemy。这在文档中没有提及。如果你发布这个答案,我会接受。 –