使用python-oracledb在Oracle 23ai上直接绑定JSON数据报错
解决oracledb直接绑定JSON时的DPY-3002错误
问题根源
你遇到的DPY-3002: Python value of type "dict" is not supported错误,核心原因是**setinputsizes方法的参数传递错误**:你的SQL语句仅包含1个绑定变量:1,但你传入了None, oracledb.DB_TYPE_JSON两个参数,导致参数位置不匹配,驱动无法正确识别要绑定的JSON类型。
另外需确认你的python-oracledb版本为2.0及以上,因为直接绑定Python字典到Oracle JSON类型的特性是从该版本开始支持的。
修复后的代码
修正setinputsizes参数,并补充事务提交操作(原代码缺少提交,插入数据不会持久化):
import os import json import random import oracledb assert "ORACLE_USER" in os.environ assert "ORACLE_PASSWORD" in os.environ assert "ORACLE_DSN" in os.environ assert "ORACLE_MODE" in os.environ assert "ORACLE_JSON_BENCH_TABLE" in os.environ if __name__ == "__main__": username = os.environ["ORACLE_USER"] password = os.environ["ORACLE_PASSWORD"] dsn = os.environ["ORACLE_DSN"] table_name = os.environ["ORACLE_JSON_BENCH_TABLE"] is_thick = os.environ["ORACLE_MODE"] == "THICK" # 检查python-oracledb版本兼容性 if oracledb.version < (2, 0): raise RuntimeError("需python-oracledb 2.0+版本以支持JSON直接绑定") # 初始化Thick模式客户端 if is_thick: oracledb.init_oracle_client() conn = oracledb.connect(user=username, password=password, dsn=dsn) # 获取数据库与客户端版本信息 client_version = 0 if not conn.thin: client_version = oracledb.clientversion()[0] db_version = int(conn.version.split(".")[0]) jsondict = dict(text="") with conn.cursor() as cur: query = f"INSERT INTO {table_name} VALUES (:1)" jsondict["text"] = jsondict["text"] + chr(random.randint(ord("A"), ord("z"))) if conn.thin or client_version >= 21: # 修正参数:仅对应单个绑定变量:1 cur.setinputsizes(oracledb.DB_TYPE_JSON) cur.execute(query, [jsondict]) else: cur.execute(query, [json.dumps(jsondict)]) conn.commit() # 提交事务,确保数据持久化 conn.close()
额外注意事项
- 表结构验证:确保目标表的列类型为
JSON,而非VARCHAR2或其他类型,否则直接绑定JSON会失败。 - 版本要求:
- Thin模式:Oracle数据库版本需12.2+,python-oracledb 2.0+支持直接绑定JSON
- Thick模式:Oracle客户端版本需21+才能支持直接绑定Python字典到JSON类型
内容的提问来源于stack exchange,提问作者Kazuma Kusu
相关产品推荐
相关产品推荐

