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

SQLAlchemy带参数执行Oracle插入查询未生效问题

问题根因

代码生成的SQL手动执行正常、程序运行无报错但数据未插入的核心原因是SQLAlchemy默认开启事务且不自动提交,执行写操作后没有手动调用commit,连接关闭时事务会自动回滚,所有写操作都会被撤销。
除此之外代码还有几个潜在隐患:

  • 用字符串格式化拼接SQL存在SQL注入风险,手动拼接日期字符串的写法高度依赖数据库端NLS_DATE_FORMAT、NLS_DATE_LANGUAGE参数配置,换环境很容易出现日期解析失败
  • 没有异常捕获和回滚逻辑,执行出错时既无法定位问题,还可能导致数据库连接泄漏
  • 手动拼接浮点型、整型参数容易出现格式转换错误
修复方案
  • 执行完写操作后手动提交事务,异常场景下回滚事务
  • 用SQLAlchemy的参数绑定语法替代字符串拼接,日期直接传原生datetime对象,由驱动完成类型适配,避免格式问题
  • 增加finally块确保连接一定会被关闭

修复后的可运行代码:

from sqlalchemy.engine import create_engine
from sqlalchemy import text
import datetime

DIALECT = 'oracle'
SQL_DRIVER = 'cx_oracle'
USERNAME = 'xxx'
PASSWORD = 'xxx'
HOST = 'pv-prod-orc-01.xxx.com'
PORT = 1521
SERVICE = 'PVL01PD_APP.ec2.internal'
ENGINE_PATH = f"{DIALECT}+{SQL_DRIVER}://{USERNAME}:{PASSWORD}@{HOST}:{PORT}/?service_name={SERVICE}"

engine = create_engine(ENGINE_PATH)
conn = engine.connect()

try:
    # 日期直接转为datetime对象,不需要手动格式化为字符串
    target_date = datetime.datetime.strptime(Date, "%Y-%m-%d")
    # 用命名参数绑定写法,避免字符串拼接
    stmt = text("call CORE_VALUATIONS.VALUATIONS.INSERTEQCLOSINGPRICE(:pkey, :closing_date, :price, NULL, NULL)")
    conn.execute(stmt, {
        "pkey": int(Pkey),
        "closing_date": target_date,
        "price": float(price)
    })
    # 核心:提交事务,否则所有修改都会被回滚
    conn.commit()
    print("价格数据插入成功")
except Exception as e:
    conn.rollback()
    print(f"插入失败,错误详情:{str(e)}")
finally:
    conn.close()
补充说明
  • 如果不想手动管理事务,可以在创建引擎时开启自动提交:engine = create_engine(ENGINE_PATH, isolation_level="AUTOCOMMIT"),但生产环境更推荐手动控制事务粒度,避免误写数据。
  • 用PL/SQL Developer、Navicat等客户端手动执行SQL能直接生效,是因为这类工具默认开启了自动提交,和程序默认的事务行为不一致,这也是两边执行结果不同的核心原因。
  • 不要手动把日期转为'01Oct2024'这类字符串传入,如果Oracle实例的日期语言配置不是英文,会直接报日期格式不匹配错误,传原生datetime对象是兼容性最好的做法。

问题运行截图:
问题运行截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 05:18:25