2016-05-12 71 views
3

我查詢並更改了多個實例。我只想將更改提交給其中一個人。但是,我致電db.session.commit()時承諾所有更改。有沒有辦法單獨保存一個對象,像Rails或Django一樣,object.save()多個已更改時只提交一個SQLAlchemy模型實例的更改

rule_1 = Rule.query.filter(Rule.something.like(that_thing)) 
rule_1.change_message = "Duplicate" 

rule_2 = Rule.query.filter(Rule.something.like(that_thing)) 
rule_2.change_message = "This is 2nd Duplicate Message" 

rule_3 = Rule.query.filter(Rule.something.like(that_thing)) 
rule_3.change_message = "This is the THIRD Duplicate Message" 

# What I want 
rule_3.save() 

回答

7

SQLAlchemy使用工作單元模式,而Django,Rails和許多其他ORM使用活動記錄模式。這意味着屬於一個會話的每件事都是一個單位。

你的問題揭示的不是SQLAlchemy的問題,而是你的工作流的一個問題。如果你不想改變這些值,你不應該改變它們。如果您錯誤地更改了某些內容,請將其從會話中刪除,而不是將它放在周圍。

rule1.change_message = 'changed rule 1' 
db.session.expunge(rule1) 
# no longer part of the session, will not be committed 
# use db.session.add(rule1) to track it again 

如果你真的,實際上,確實需要工作的獨立單元(你最有可能沒有),創建單獨的會話,並用它們來查詢不同的實例。

Flask-SQLAlchemy每個上下文使用一個會話,因此所有的查詢都將這些實例放在同一個會話中。 query參數使用此默認會話。您可以致電create_session創建單獨的會話。確保手動清理這些會話。

session1 = db.create_session({}) 
rule1 = session1.query(Rule).filter_by(name='rule1').one() 
rule1.message = 'message' 

session2 = db.create_session({}) 
rule2 = session2.query(Rule).filter_by(name='rule2').one() 
rule2.message = 'message' 
session2.commit() # only commits rule2 

session1.close() 
session2.close() 
0

Rule.query只是一個別名db.session.query(Rule),你正在做在同一會話的不同請求的會話將被COMMITED作爲一個整體。我不是專家,但要做你想做的事情,你必須爲每個需要的更新創建一個會話。

這工作,但我不知道這是否是最好的方法:

db = SQLAlchemy(app) 
# new session created from your db instance with default parameters 
new_session = db.create_session({}) 

rule_1 = Rule.query.filter(Rule.something.like(that_thing)) 
# or 
# rule_1 = db.session.query(Rule).filter(Rule.something.like(that_thing)) 
rule_1.change_message = "Duplicate" 

rule_2 = new_session.query(Rule).filter(Rule.something.like(that_thing)) 
rule_2.change_message = "This is 2nd Duplicate Message" 

# update rule_1 
db.session.commit() 

# update rule_2 
new_session.commit() 
相關問題