当多个更改

时间:2016-05-12 15:17:49

标签: python flask sqlalchemy flask-sqlalchemy

我查询并更改了几个实例。我只想将更改提交给其中一个。但是,当我致电db.session.commit()时,所有更改都会提交。有没有办法单独保存对象,object.save(),如Rails或Django?

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() 

2 个答案:

答案 0 :(得分:12)

SQLAlchemy使用工作单元模式,而Django,Rails和许多其他ORM使用活动记录模式。这意味着属于一个会话的所有内容都充当一个单元。

您的问题显示的不是SQLAlchemy的问题,而是您的工作流程的问题。如果您不想更改这些值,则不应更改它们。如果您错误地更改了某些内容,请将其从会话中删除,而不是将其遗留下来。

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var SalesSchema = new Schema({
    owner: { type: Schema.Types.ObjectId, ref: 'User'},
    total: { type: Number, default: 0},
    items: [{
        item: { type: Schema.Types.ObjectId, ref: 'Product'},
        itemName: { type: String, default: "no name provided"},
        cartQuantity: { type: Number, default: 1 },
        price: { type: Number, default: 0 }
    }],
    date: Date
});

module.exports = mongoose.model('Sale', SalesSchema);

如果你真的,实际上,肯定需要单独的工作单元(你很可能不会),创建单独的会话并使用它们来查询单独的实例。

Flask-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 参数使用此默认会话。您可以通过调用query创建单独的会话。确保手动清理这些会话。

create_session

答案 1 :(得分: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()