2016-05-12 7 views
3

複数のインスタンスを照会および変更しました。私はそのうちの1つに変更をコミットしたいだけです。ただし、db.session.commit()と呼ぶと、すべての変更がコミットされます。 RailsやDjangoのようにオブジェクトを個別に保存する方法はありますか?object.save()複数のSQLAlchemyモデルインスタンスが変更された場合に、1つの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はアクティブなレコードパターンを使用します。つまり、1つのセッションに属するすべてが1つの単位として機能します。

問題が明らかになったことは、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はコンテキストごとに1つのセッションを使用するため、すべてのクエリによってすべてのインスタンスが同じセッションに配置されます。 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)にちょうどエイリアスです。私は専門家ではありませんが、あなたが望むことをするためには、必要なすべての更新のためにセッションを作成する必要があります。

これは動作しますが、私はそれが最善のアプローチであるかどうかわからないんだけど:

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() 
関連する問題