SQLAlchemy 更新会话超出范围的行

SQLAlchemy Update row where session has gone out of scope

我有一个现有的获取方法。

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

我在此处找到的每个示例都显示创建会话、执行 select、执行更新,然后 flush/commit 都在一个方法中完成。如果不需要,我宁愿不复制 GET。

理想情况下,我希望这一切都是像 bulk_update_mappings 这样的单一查询,并且只访问数据库一次,但我认为没有主键我无法做到这一点。

直接更新 table,如果不需要,请不要获取/更新/保存实例。

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 将数据绑定到命名占位符,然后传递一个字典列表,其中键与占位符的名称匹配。在这种情况下,它是 'key''value',但它可以是任何东西,当然你可以在 .values() 中使用许多参数。该示例假定您的 table 中的业务键字段名为 business_key,而您要更新的字段名为 field_to_set.

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

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

参考this SQLAlchemy doc