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
相关产品推荐
相关产品推荐

