记Python连接Oracle数据库的各种问题

记Python连接Oracle数据库的各种问题因为单位管理系统老旧落后,需要实现一些新功能,作为新上任的信息科工程师,正好拿来练练手。 新功能需要从数据库中读取数据,一开始我选择python。

因为医院的管理系统老旧落后,需要实现一些新功能,作为新上任的信息科工程师,正好拿来练练手。 新功能需要从数据库中读取数据,一开始我选择python。

连接数据库

从百度,到第一次连上数据库,我花了整整两天,可算找到一点门道。 其中走了一条很大的弯路

网上说连接数据库需要版本配合,这里的版本不需要考虑数据库服务端的版本。起码,新的cx_Oracle和最新的instantclient能够连接10g版本 起初为了考虑兼容10g服务端,我要用老版的cx_Oracle,老板的Python,老版的instantclient,一趟折腾下来,还总是异常。 我气的差点砸键盘,冷静半天后,我决定用其他的语言试试,于是挑了扔下很久的C#。结果…… 微软爸爸太牛逼了😭 只需要引用一个nuget包,直接搞定!!!包名貌似是: Oracle.ManagedDataAccess.Client.Core 这个时候,我才意识到,根本不用执着于服务端的数据库版本。 因为种种原因,我最后回到了Python,因为动态语言就是香……

读取中文数据乱码

好不容易连上数据库,能够正常查询了,又遇到一个棘手的问题:中文乱码 起初,我以为是配置问题,python连接时不能设置解码器,于是尝试了C#和JS连接,都不能解决问题。 又是一番百度,我找到了数据库的语言设置,终于发现数据库建立时,用UTF作为nvchar的编码格式,但是实际保存的字节是用gbk编码的,所以不管怎么设置NLS_LANG,要么连接错误,要么读取的中文都是乱码。 我一边骂当初的设计者傻X,一边打算投降了。😒

解决乱码

在B站上浪了一天,中二之力充满,我觉得自己又行了,灵机一动,想到一个办法:重新解码中文 实现这个目的,需要两步:

读取原始的字节序列

这点可以通过Oracle函数rawtohex(column_name)实现

重新编码

这一步也不难,只需Python一行代码 bytes.fromhex(byte_str).decode('gbk')

最后,把两步合起来,组成一个对使用者透明的api

def query(query_table,query_fields:Union[list[str],str],decode_fields:list[str]=None,filters:str=None):
    sql='select '
    sql+='T.'+query_fields if isinstance(query_fields,str) else ','.join(query_fields)

    for field in decode_fields:
        sql+=f',rawtohex({field})'
    sql+=f' from {query_table} T'

    if filters:
        sql+=' '+filters


    print('Query:',sql)

    with cx_Oracle.connect('user','pwd','ip/orcl') as connection:
        with connection.cursor() as cursor:
            cursor.execute(sql)
            col_names=[col[0] for col in cursor.description]
            rows=format_rows(col_names,cursor.fetchall())

    if decode_fields:
        for i in range(len(rows)):
            row=rows[i]
            keys=list(row.keys())
            for key in keys:
                if key.lower().startswith('raw'):
                    decode_str=decodegbk(row[key])
                    for field in decode_fields:
                        if field.lower() in key.lower():
                            row[field.upper()]=decode_str
                            del row[key]
                            break
    return rows

今天的文章记Python连接Oracle数据库的各种问题分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19754.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注