Linux系统通过python访问SQL SERVER,无法显示数据库内中文的问题

最近遇到几个需求,需要从centos上通过python访问sql server服务器查询数据,本来倒也不是很复杂,通过pyodbc比较顺利地实现了,具体如下:

 

  1. 先直接通过yum安装unixODBC、unixODBC-devel和freetds (pyodbc需要)
  2. 然后源码编译安装pyodbc
  3. 配置/etc/odbcinst.ini,添加连接sql server的数据源信息 (路径按实际情况填写)
[SQL Server]
Description     = FreeTDS ODBC driver for MSSQL
Driver      = /usr/local/freetds/lib/libtdsodbc.so
Setup       = /usr/local/freetds/lib/libtdsS.so
FileUsage       = 1

 配置完成后就可以直接访问sql server数据库进行查询了

#!/usr/bin/env python
#-*- encoding: utf-8 -*-
import pyodbc
conn=pyodbc.connect('DRIVER={SQL Server};SERVER=xxx.xxx.xxx.xxx;port=1433;DATABASE=testdb;UID=user;PWD=password')
cursor=conn.cursor()
cursor.execute("select name from test")
row=cursor.fetchone()
print row[0]

 

然而,还没有高兴多久就发现一个大问题,数据库中存储的中文字符不能正常显示,全部变成了问号。这其实也很正常,因为sql server里面的字符编码不是通用的utf-8(所以说windows上的东西就是难搞啊)。虽然知道原因,但是要解决这个问题却也不是很容易,在对freetds的charset设置和pyodbc连接的charset设置进行各种调整尝试,返回结果也各种encode、decode之后,问号依然是顽强的问号。

 

在被问号折腾了好久快要放弃的时候,终于找到了解决办法。究其根本原因,还是Linux和window系统间的不同字符集问题,这实在是个难翻的墙啊。freetds会做字符集的默认转换,结果就是这个转换导致了中文变问号。解决方法:

  1. 首先,freetds必须源码安装,在编译时指定参数disable-libiconv,禁止自动转换:./configure --enable-msdblib --prefix=/usr/local/freetds --with-tdsver=8.0 --disable-libiconv
  2. 然后,连接数据库时需要指定tds_version参数,版本太低会有问题,我用的是8.0(访问sql server 2008 R2)
  3. 在获取返回结果时,由于sql server内部是gbk编码的,因此需要把结果从gbk进行解码,这样才能在utf8环境中正常显示。
conn=pyodbc.connect('DRIVER={SQL Server};SERVER=xxx.xxx.xxx.xxx;port=1433;DATABASE=testdb;UID=user;PWD=password;TDS_Version=8.0')
cursor=conn.cursor()
cursor.execute("select name from test")
row=cursor.fetchone()
print row[0].decode('gbk')

 

这样,终于成功地把中文正常显示出来了!不过还需要注意,如果中文字符在sql server中是使用unicode方式存储的(nvarchar nchar),那么还是会乱码,不过这个问题也很容易处理,在select的时候进行下转换即可,例如select convert(varchar,name) as name

 

 

 

 

 

你可能感兴趣的:(linux,python,SQL Server,字符集)