好吧,虽然我目前是一个pg党,但是有的时候这个数据库的选择不是我说了算的,最近就碰到需要连接SQLServer的情况。
由于是linux的环境,网上搜刮了一下,找到了pymssql。安装甚是方便,前提是已经安装了freetds和Cython。另外提一下,freetds需要加上mssql的支持,在macport下就是:
%% sudo port install freetds +mssql
至于ArchLinux,默认就已经把这个选项加进去了:P
照理说这个故事到现在就算结束了,可以问题很快又暴露了出来,SQLServer没有使用我们喜闻乐见的UTF-8,而数据表名里面居然还有中文字符……
按照一般的思维,这个也不是什么难事,直接转一次码也就行了:
cursor.execute(u'blablabla'.encode('gbk'))
这个方法在一台安装了freetds 0.6的CentOS上是没有问题的,可是同样的代码,在安装了freetds 0.82的Arch和Mac上全部报错!Python相关的包版本都是一样的,想来想去也只有freetds的问题了。
又是苦苦寻觅了半天,终于给摸着点头绪,原来在freetds配置文件freetds.conf里面(不知道在哪儿?locate之 = =)有一个client charset的参数,以下是官方对其的解释:
Makes FreeTDS use iconv to convert to and from the specified character set from UCS-2 in TDS 7.0/8.0. As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need to match the server's charset to insert any characters the server supports.
其实看了说明之后也不是挺明白到底怎么回事的,这仅仅是说client端的编码而已,并不是指定server端的编码,那对freetds来说信息还是不对称,它又怎么知道我需要传送到server的其实是GBK码呢?感觉整个逻辑挺乱的……现在看来大概是CentOS上的freetds 0.6还没有加入这个功能,对client传输的数据没有进行转码,所以没碰上现在这么个问题。
虽然还是云里雾里的,但是既然知道了freetds会作转码,而通过pymssql传送的数据是gbk的,那么还是在配置文件里面申明一下吧。
[hostname]
host = the real host
client charset = GBK
经过这样的设定,终于万事大吉了。其中,hostname是我们在用pymssql连接时使用的主机名,可以起别名比如sb01这样的,然后用pymssql.connect(host='sb01', ...)这样的代码连接就可以了。需要注意的是,这GBK需要大写,这烦人的设定……
这事终于告一段落,虽然解决的还是挺莫名的,但管它呢,最好以后别让我碰上utf8之外的东西了……

