Linux服务器Python通过OPENROWSET BULK导入SQLServer特殊字符乱码
解决Linux下Python生成CSV插入SQL Server 2008的乱码问题
问题根源
- Linux系统没有
ANSI编码别名(ANSI是Windows专属,西语环境对应cp1252编码),直接用encoding='ANSI'会报错。 - SQL Server 2008对UTF-8的原生支持有限,无BOM的UTF-8文件无法被OPENROWSET正确识别。
- 格式文件的编码配置与CSV文件编码不匹配,导致特殊字符解析错误。
解决方案
方案1:使用CP1252编码生成CSV(匹配原Windows环境的ANSI)
将Python生成CSV的代码中encoding='ANSI'替换为encoding='cp1252',Linux系统支持该编码,生成的CSV与Windows下的ANSI文件编码一致:
dfClientes.to_csv(cvs_path, index=False, sep=';', encoding='cp1252')
此时无需修改格式文件和SQL语句,因为格式文件中指定的COLLATION="SQL_Latin1_General_CP1_CI_AS"正好对应CP1252编码,能正确解析Ñ、á、é等特殊字符。
方案2:使用UTF-8编码(需适配SQL Server 2008)
如果坚持用UTF-8,需要同时修改Python代码和SQL语句:
- 生成带BOM的UTF-8文件:Python中使用
utf-8-sig编码,自动添加UTF-8 BOM,让SQL Server能识别编码:
dfClientes.to_csv(cvs_path, index=False, sep=';', encoding='utf-8-sig')
- 修改OPENROWSET语句:添加
CODEPAGE='65001'参数(65001是UTF-8的代码页):
bulk_insert_query = f'''INSERT INTO sgCliente (IdCliente,NomCliente,ApeCliente,NumDocumento,IdTipoDoc,NomTipoDoc,CodTipoDoc,Tip_docu,Sexo,FactorRh,GrupSangre,EstadoCivil,FecNacimiento,eMail,TelMovil,PrimerNombre,SegundoNombre,PrimerApellido,SegundoApellido,IndCentroExcelencia,IndDatosPersonal,IndHabilitado,IdTercero,CodUES) SELECT * FROM OPENROWSET( BULK '{ ruta_destinoCSV }', FORMATFILE='{ ruta_destinoXML }', FIRSTROW = 2, CODEPAGE='65001') as t '''
额外检查:数据库表字段类型
确保表中存储特殊字符的字段(如NomCliente、ApeCliente等)使用NVARCHAR类型而非VARCHAR。NVARCHAR是Unicode类型,能原生支持所有特殊字符,避免因字符集不兼容导致的乱码。
内容的提问来源于stack exchange,提问作者ANDREA CAROLINA CAMACHO JULIO
相关产品推荐
相关产品推荐

