Flask-SQLAlchemy调用PostgreSQL存储过程不执行问题排查
问题原因定位
以下是导致存储过程未触发的核心原因:
- 缺少事务提交:通过
db.engine.raw_connection()获取的是psycopg2底层连接,默认关闭自动提交,存储过程执行后未显式提交的话,所有操作会在连接关闭时自动回滚,表现为存储过程未被触发。 - 资源未正确管理:未对cursor、连接做生命周期管理,连接泄露或异常关闭也会导致执行结果未持久化。
- 驱动适配问题:psycopg2的
callproc方法对PostgreSQL原生PROCEDURE类型的存储过程兼容性有限,部分版本会出现调用不生效的问题。
修复方案
方案1:修复原有raw_connection写法
from flask import Flask from flask_sqlalchemy import SQLAlchemy con_str = 'postgresql://user:password@IP_PostgresDB:5432/base' app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = con_str db = SQLAlchemy(app) # 上下文管理器自动释放连接和cursor资源 with db.engine.raw_connection() as conn: with conn.cursor() as cur: cur.callproc("usp_pes_pessoa", [1]) # 显式提交事务 conn.commit() # 如需获取返回结果可调用 cur.fetchall()
方案2:SQLAlchemy 14 标准调用写法(兼容性更好)
直接使用SQLAlchemy核心层接口调用,不需要操作底层DBAPI连接:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy import text con_str = 'postgresql://user:password@IP_PostgresDB:5432/base' app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = con_str db = SQLAlchemy(app) with db.engine.connect() as conn: # PostgreSQL存储过程使用CALL语句调用 conn.execute(text("CALL usp_pes_pessoa(:param)"), {"param": 1}) conn.commit()
补充排查点
如果调整后仍未生效,可按以下顺序排查:
- 确认存储过程的创建类型:如果是用
CREATE FUNCTION创建的函数,需要用SELECT usp_pes_pessoa(1)语句调用,不支持CALL语法。 - 确认连接使用的数据库账号拥有该存储过程的执行权限。
- 开启SQLAlchemy日志打印执行语句,验证请求是否实际发送到数据库:添加配置
app.config["SQLALCHEMY_ECHO"] = True。
内容的提问来源于stack exchange,提问作者Fperuso
相关产品推荐
相关产品推荐

