通过 SQLAlchemy 使用 Postgresql 执行多条语句不会持久化更改 [英] Executing multiple statements with Postgresql via SQLAlchemy does not persist changes

查看:24
本文介绍了通过 SQLAlchemy 使用 Postgresql 执行多条语句不会持久化更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这不起作用 - 更新无效:

This does not work – the update has no effect:

command = "select content from blog where slug = 'meow'; update account_balance set balance=200 where id=1; select 1 from blog;"
content = db.engine.scalar(command)

切换语句执行更新和选择成功:

Switching the statements performs the update and select successfully:

command = "update account_balance set balance=200 where id=1; select content from blog where slug = 'meow';"
content = db.engine.scalar(command)

为什么第一个不起作用?它适用于 Pgadmin.我使用 Flask-Sqlalchemy 启用了自动提交.

Why does the first not work? It works in Pgadmin. I enabled autocommit with Flask-Sqlalchemy.

我正在做一个关于 SQL 注入的研讨会,所以请不要重写解决方案!

I am doing a workshop on SQL injection, so please dont rewrite the solution!

推荐答案

SQLAlchemy 的自动提交的工作方式是检查发出的语句,尝试 检测数据是否被修改:

The way SQLAlchemy's autocommit works is that it inspects the issued statements, trying to detect whether or not data is modified:

...,SQLAlchemy 实现了自己的自动提交"功能,该功能在所有后端都完全一致.这是通过检测表示数据更改操作的语句(即 INSERT、UPDATE、DELETE 以及数据定义语言 (DDL) 语句(例如 CREATE TABLE、ALTER TABLE),然后在没有正在进行的事务时自动发出 COMMIT 来实现的).检测基于语句中是否存在 autocommit=True 执行选项.如果语句是纯文本语句并且未设置标志,则使用正则表达式来检测针对特定后端的 INSERT、UPDATE、DELETE 以及各种其他命令

..., SQLAlchemy implements its own "autocommit" feature which works completely consistently across all backends. This is achieved by detecting statements which represent data-changing operations, i.e. INSERT, UPDATE, DELETE, as well as data definition language (DDL) statements such as CREATE TABLE, ALTER TABLE, and then issuing a COMMIT automatically if no transaction is in progress. The detection is based on the presence of the autocommit=True execution option on the statement. If the statement is a text-only statement and the flag is not set, a regular expression is used to detect INSERT, UPDATE, DELETE, as well as a variety of other commands for a particular backend

由于不支持多个结果集 在 SQLAlchemy 级别,在您的第一个示例中,检测只是省略了发出 COMMIT,因为 first 语句是一个 SELECT,而在您的第二个示例中,它是一个 UPDATE.不会尝试从多个语句中检测数据修改语句.

Since multiple result sets are not supported at SQLAlchemy level, in your first example the detection simply omits issuing a COMMIT because the first statement is a SELECT, where as in your second example it is an UPDATE. No attempt to detect data modifying statements from multiple statements takes place.

如果你看看PGExecutionContext.should_autocommit_text(),你会看到它做了一个正则表达式匹配针对AUTOCOMMIT_REGEXP.换句话说,它只匹配文本的开头.

If you look at PGExecutionContext.should_autocommit_text(), you'll see that it does a regex match against AUTOCOMMIT_REGEXP. In other words it matches only at the beginning of the text.

这篇关于通过 SQLAlchemy 使用 Postgresql 执行多条语句不会持久化更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆