我试图通过Python2(Flask)API从Python3(Django)应用程序中获取特殊字符(例如:ñ、ủ、é),并将其输入Oracle数据库(Oracle 19c Enterprise)。这取代了一个Java应用程序,该应用程序可以直接访问数据库,并且能够保存特殊字符而不会出现任何问题
为了使用特殊字符进行API调用,我发现必须对值进行URL编码:
>>> comment = "Joëlle Küsel Núñez-Chaillüé"
>>> urllib.parse.quote(comment).encode('utf-8')
b'Jo%C3%ABlle%20K%C3%BCsel%20N%C3%BA%C3%B1ez-Chaillu%CC%88%C3%A9'
该字符串将被发送到Python2API。我最初的尝试涉及在将其发送到Oracle之前在Python 2中对其进行解码,但是,任何将值传递到cx_Oracle的尝试都会导致'ascii' codec can't encode characters in position 3-4: ordinal not in range(128)
我试图通过直接将URL编码字符串传递给Oracle来解决这个问题:
>>> comment_blob = cx.cursor().var(cx_Oracle.BLOB)
>>> comment_blob.setvalue(0, bytes(u'{}'.format(comment.decode('utf-8'))))
在Oracle中,我尝试解码该值:
v_comment := UTL_RAW.CAST_TO_VARCHAR2( parameter );
v_comment := convert(utl_url.unescape(v_comment), 'WE8ISO8859P15');
这适用于除ủ之外的所有内容,在某些情况下,ủ会被其后面的字符覆盖(但粘贴到任何其他文本编辑器时会正确显示),有时会被更改为完全不同的字符。例如:
Joëlle Küsel Núñez-Chaillüé
Joëlle Kÿsel Núñez-Chaillüé
字符9从ü变为ÿ,虽然最后两个字符在这里看起来是正确的,但在SQL Developer中,它们组合成一个字符(通过旧Java应用程序插入的值在SQL Developer中正确显示)
你知道我为什么只对你的角色有意见吗
如果您有旧的cx_Oracle模块,则在创建连接时需要指定字符集,例如:
如果升级到cx_Oracle 8,则此字符集是默认字符集,因此可以省略
encoding
选项。见Setting the Client Character Set其他两项说明:
计划升级到Python3,因为Python2已不再开发。Python3还改变了文本和字节的内部处理
希望您实际使用的是连接池,请参见How to use Python Flask with Oracle Database
我想出了一个有效的(虽然不理想)解决方案来解决我的问题。在我的Python3(Django)应用程序中,我将字符串转换为字符代码列表。我通过Python2API传递代码列表,而不做任何操作,然后使用PL/SQL将其转换回常规字符
Django代码:
Python 2 API:
甲骨文:
这个方便的ASCII字符代码列表是一个很好的资源:
https://www.techonthenet.com/ascii/chart.php
相关问题 更多 >
编程相关推荐