SQLAlchemy更新会话超出范围的行

时间:2017-06-01 15:15:22

标签: python sqlalchemy updates

我有一个现有的get方法。

    def get_parameter(self, app, my_business_key):
        my_db = MultiTenantSQLAlchemy(app)
        session = my_db.get_session(app)
        return session.query(MyParameter).filter(MyParameter.my_business_key.in_(my_business_key)).all()

由于我没有主键,而且我正在使用业务键进行更新,我的假设是我必须首先提取记录。

我获取参数对象,对其进行更新然后想要保存它们。

    def save_parameters(self, app, my_business_key, my_parameters):
        my_db = MultiTenantSQLAlchemy(app)
        session = lro_db.get_session(app)

        # session.Update(my_parameters)    ?????

        session.flush()
        session.commit() 

我在这里找到的每个例子都显示了创建会话,执行选择,执行更新,然后在一个方法中刷新/提交所有内容。如果我不需要,我宁可不复制GET。

理想情况下,我喜欢这一切都是像bulk_update_mappings这样的单一查询,而且只去过DB一次,但我不认为没有主键我就能做到这一点。

1 个答案:

答案 0 :(得分:1)

直接更新表,如果没有,请不要获取/更新/保存实例。

my_table = MyORMClass.__table__
update_statement = (
    my_table.update()
            .where(my_table.c.business_key == bindparam('key'))
            .values(field_to_set=bindparam('value')))
session.execute(update_statement, [
    {'key': 100, 'value': 'value for 100'},
    {'key': 200, 'value': 'value for 200'},
])

此处更新发生在一次往返中。

这个想法是你使用bindparam将数据绑定到命名占位符,然后传递一个dicts列表,其中键与占位符的名称相匹配。在这种情况下,它是'key''value',但它可以是任何内容,当然您可以在.values()中使用许多参数。该示例假定业务键字段在表中名为business_key,并且您要更新的字段名为field_to_set

请注意.where() ans .values()之间的区别:一个采用由列对象和==组成的条件,另一个采用普通的命名参数。

当然,您可以通过编程方式构建更新列表,为简单起见,我只是在这里显示一个常量。

请参阅this SQLAlchemy doc以供参考。