2016-01-13 82 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。這在文檔中沒有提及。如果你發佈這個答案,我會接受。 –