You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy 2.0执行GRANT/DELETE无数据库变更,旧版本正常

SQLAlchemy 2.0中GRANT/DELETE语句无效果的解决方法

问题原因

SQLAlchemy 2.0对事务管理做了关键变更:

  • 1.3版本中,执行DDL(如GRANT)或DML(如DELETE)时,连接默认会自动提交事务
  • 2.0版本中,engine.connect()获取的连接会自动开启事务,且不会自动提交。如果没有显式提交,所有修改操作都会在上下文结束时回滚,导致数据库无变更

解决方案

方法1:显式提交事务

在执行完修改语句后,调用连接的commit()方法:

query_2 = "GRANT SELECT ON TABLE '<schema>'.'<table_name>' TO '<some_user>'"
query_3 = "DELETE FROM '<schema>'.'<table_name>' WHERE <some condition>"
with engine.connect() as con:
    con.execute(text(query_2))
    con.execute(text(query_3))
    con.commit()  # 显式提交事务

方法2:使用engine.begin()上下文管理器

begin()会自动处理事务的提交和异常回滚,更简洁安全:

query_2 = "GRANT SELECT ON TABLE '<schema>'.'<table_name>' TO '<some_user>'"
query_3 = "DELETE FROM '<schema>'.'<table_name>' WHERE <some condition>"
with engine.begin() as con:
    con.execute(text(query_2))
    con.execute(text(query_3))
# 上下文结束时自动提交,异常时自动回滚

方法3:为单个语句开启自动提交

针对DDL语句,可以给text()设置execution_options(autocommit=True):

with engine.connect() as con:
    con.execute(text(query_2).execution_options(autocommit=True))
    con.execute(text(query_3))
    con.commit()  # DELETE仍需提交,或者也单独设置autocommit

额外注意

你的SQL语句中使用单引号包裹标识符(如<schema>、<table_name>),PostgreSQL标准中标识符应该用双引号包裹,如果标识符是小写且符合规则可以省略引号。虽然SELECT能正常执行,但这可能在某些场景下引发问题,建议调整为:

GRANT SELECT ON TABLE "<schema>"."<table_name>" TO "<some_user>"

内容的提问来源于stack exchange,提问作者Docuemada

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 09:07:08