Python 通过SQLAlchemy使用Postgresql执行多个语句不会持久化更改

Python 通过SQLAlchemy使用Postgresql执行多个语句不会持久化更改,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,这不起作用–更新无效: 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) 切换语句将执行更新并成功选择: command = "update account_balance set balance=200 where

这不起作用–更新无效:

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)
切换语句将执行更新并成功选择:

command = "update account_balance set balance=200 where id=1; select content from blog where slug = 'meow';"
content = db.engine.scalar(command)
为什么第一个不起作用?它在Pgadmin中工作。我用炼金术启用了自动提交


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

如果希望执行所有操作并只获取第一行,则应使用
db.engine.execute(…).first()

SQLAlchemy的自动提交工作方式是它检查已发布的语句,尝试:

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

因为在SQLAlchemy级别,在第一个示例中,检测只是省略了发出COMMIT,因为第一个语句是SELECT,而在第二个示例中它是UPDATE。没有尝试从多个语句中检测数据修改语句


如果你看一看,你会发现它有反作用。换句话说,它仅在文本开头匹配。

如果要使用
创建表格,请选择“进入”

如上所述,
engine.execute('select*into a from b')
不起作用。相反,您可以执行以下操作:

conn=engine.raw\u连接()
游标=连接游标()
cursor.execute('select*into a from b')
康涅狄格州提交

定义“不起作用”?没错。@CraigRinger账户余额行当然不会更新course@IljaEverilä,我没有收到错误,因为db执行了它们,但是update语句没有错误effect@IljaEveril你是对的。我忘了写些东西来避免这个错误。我使用1.1.12I添加了一个
commit
,现在它可以工作了。SQLAlchemy一定忘了自己发布。您是否猜测SQLA会检查最后一条语句是否应该发出commit?对不起,我修正了答案。重要的是第一条语句(如在第二个示例中,第一条语句是UPDATE)。还添加了一些背景说明为什么。哇,真的吗?这是一种疯狂的实现方式。不要使用那个功能@craig ringer它适用于单文本SQL语句,如果您真的需要多语句SQL字符串(SQLA似乎不支持,但留给DBAPI级别)和自动提交,则有
text(…)。执行选项(autocommit=True)
,如中所述,虽然我想这更常用于表示函数或SP改变数据并应提交的信号。另一方面,就我个人而言,我一般不喜欢自动提交。如果使用
SELECT insert\u something(…)
,它不会失败吗?