python-oracledb Thin模式直接绑定JSON列致客户端无法读取问题
问题背景
使用python-oracledb的Thin模式,通过显式指定DB_TYPE_JSON绑定并插入JSON数据后,无报错但各类数据库客户端无法正常显示JSON列(如DataGrip抛出java.lang.UnsupportedOperationException),而Thick模式下插入的记录可正常显示。
疑问1:为何Thin模式下指定DB_TYPE_JSON无报错?
python-oracledb 2.2.1版本的Thin模式中,DB_TYPE_JSON的直接绑定逻辑存在实现缺陷:它并未按照Oracle要求的原生二进制JSON(OJSON)格式序列化Python字典,而是以非标准的格式写入JSON列。
Oracle的JSON列具备兼容性,允许接收非标准格式的数据而不触发报错,但这种数据无法被第三方客户端(如DataGrip)识别解析,因此出现"无报错但无法显示"的矛盾现象。
疑问2:除切换Thick模式外的替代方案
以下是三种可行的替代方案:
移除显式类型绑定,依赖自动序列化
删除cur.setinputsizes(None, oracledb.DB_TYPE_JSON)这一行代码,直接传入Python字典。oracledb会自动将字典序列化为标准JSON字符串,Oracle数据库会自动将字符串转换为原生JSON格式存储,客户端可正常读取显示。
修改后的插入代码:def insert_json( cur: oracledb.Cursor, id: str, json_data: Dict, ): query: str = "INSERT INTO json_data VALUES (:1, :2)" cur.execute(query, [id, json_data])手动序列化JSON字符串后插入
使用Python标准库json将字典序列化为字符串后再插入,同样能让Oracle正确解析为原生JSON格式:import json def insert_json( cur: oracledb.Cursor, id: str, json_data: Dict, ): query: str = "INSERT INTO json_data VALUES (:1, :2)" cur.execute(query, [id, json.dumps(json_data)])升级python-oracledb版本
升级至3.x及以上版本,后续版本已修复Thin模式下DB_TYPE_JSON的绑定缺陷,完善了对Oracle原生JSON格式的支持,可正常使用显式类型绑定。
内容的提问来源于stack exchange,提问作者Kazuma Kusu

