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

Python抽取Oracle数据库多字节字符时编码异常的解决问询

问题描述

从Oracle数据库抽取数据导出至CSV文件时遇到编码相关问题:

  • 使用默认UTF-8编码时,抛出错误:'utf-8' codec can't decode byte 0xd1 in position 14: invalid continuation byte
  • 数据库字符集为AL32UTF8,国家字符集为AL16UTF8,部分西班牙文ñ字符被替换为?
  • 尝试改用ISO-8859-1编码后,前两个查询可正常运行,但其他查询出现partial multibyte character错误,仍存在字符被替换为?的情况
解决步骤
  • 对齐连接编码与数据库字符集:数据库字符集是AL32UTF8,连接时直接使用UTF-8编码,同时确保NLS_LANG环境变量与数据库字符集保持一致,避免编码转换冲突。
  • 指定国家字符集编码:cx_Oracle连接时额外设置nencoding="UTF-16",匹配数据库的AL16UTF8国家字符集,确保所有字符类型数据正确读取。
  • CSV导出用标准UTF-8:导出时使用utf-8编码(如需兼容Excel可改用utf-8-sig),避免使用UTF-16这类兼容性较差的编码。
修正后的代码
import os
import cx_Oracle
import pandas as pd
from os.path import exists

# 设置NLS_LANG匹配数据库字符集
os.environ['NLS_LANG'] = 'AMERICAN_AMERICA.AL32UTF8'

connection = None
cursor = None

dir_path = './csv_files/'
queries = {
    'file1.csv': "SELECT * FROM table1",
    'file2.csv': "SELECT * FROM table2",
}

if not exists(dir_path):
    os.makedirs(dir_path)

try:
    dsn_tns = cx_Oracle.makedsn('171.11.1.111', '1521', sid='ñññ')
    # 连接时指定正确的编码和国家字符集
    connection = cx_Oracle.connect(
        user='your_user', 
        password='your_password', 
        dsn=dsn_tns, 
        encoding="UTF-8",
        nencoding="UTF-16"
    )
    cursor = connection.cursor()

    for file_name, query in queries.items():
        try:
            cursor.execute(query)
            rows = cursor.fetchall()
            columns = [col[0] for col in cursor.description]
            df = pd.DataFrame(rows, columns=columns)
            
            file_path = os.path.join(dir_path, file_name)
            # 使用UTF-8导出,兼容Excel可替换为'utf-8-sig'
            df.to_csv(file_path, index=False, encoding='utf-8', errors='strict')
            
        except Exception as e:
            print(f"处理{file_name}时出错: {e}")
            continue

except Exception as e:
    print(f"连接数据库出错: {e}")

finally:
    if cursor:
        cursor.close()
    if connection:
        connection.close()
关键注意点
  • encoding和nencoding必须分别匹配数据库的字符集和国家字符集,确保Python与Oracle之间的字符传递无转换损耗。
  • 导出时使用errors='strict'可以及时发现未处理的编码异常,便于排查问题,而非直接替换为?掩盖错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:07:16