2017-04-02 73 views
1

我試圖在特定的表上發生插入後執行一些操作。SAWarning:執行階段當前不支持'Session.add()'操作的使用

user = ModelFactory.create_user(username, email, password) 
db.session.add(user) 
db.session.commit() 

所以我創建了一個自動調用after_insert的方法。

def notify_user(user): 
    print user.id 
    book = Book(author=user.id, name='foo') 
    db.session.add(book) 
    db.session.commit(book) 

@event.listens_for(User, 'after_insert') 
def receive_after_insert(mapper, connection, target): 
    print target 
    notify_user(target) 

但這代碼顯示的警告一樣,

SAWarning: Usage of the 'Session.add()' operation is not currently supported within the execution stage of the flush process. Results may not be consistent. Consider using alternative event listeners or connection-level operations instead. 
    % method) 

/home/avinash/.virtualenvs/s2s/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py:68: SAWarning: An exception has occurred during handling of a previous exception. The previous exception is: 
<class 'sqlalchemy.exc.ResourceClosedError'> This transaction is closed 

This後顯示,我們要做的before_flush工作。我試着移動before_flush方法中的邏輯,但它顯示user.id是None。是的,這是預期的,因爲實體不會被提交給db。

同樣,我試過after_flush事件,但我仍然得到相同的警告。

回答

1

after_flush事件做工作:

@event.listens_for(User, "after_insert") 
def receive_after_insert(mapper, connection, user): 
    print(user.id) 
    @event.listens_for(Session, "after_flush", once=True) 
    def receive_after_flush(session, context): 
     session.add(Book(author=user.id, name="foo")) 

但是,爲什麼你不希望使User.author而不是有關係?

+0

在通知用戶方法的開始處,我添加了db.session.flush(),它的工作原理是 –

+0

@AvinashRaj我覺得你沒有充分發揮ORM的潛力。 ORM的一個主要特性是能夠確定插入對象的順序,以便能夠填寫外鍵。 – univerio

+0

你的意思是'db.session'是'Session'? –