pypyodbc,unixODBC和mdbtools

pypyodbc

pypyodbc是一个使用纯python实现的跨平台odbc模块,其利用了ctypes来访问底层的odbc驱动,支持python2和python3。
虽然跨平台,但其对linux/mac平台上的unixODBC支持存在问题,无法正确显示中文字段名和字段值。

unixODBC

unixODBC有几个函数的ansi版本和宽字符版本返回信息比较古怪。

首先说SQLDescribeCol,其ansi版本,也就是不带后缀W的版本,无论本地locale为何皆直接返回utf-8编码的字符,但是SQLDescribeColW版本在mac平台上返回utf-16编码的字符,linux平台对于中文字符返回的是用zero填充了每一个utf-8编码字节的神一样的编码

如下面所示:

1
'\\xe5\\x00\\x9b\\x00\\xbe\\x00\\xe5\\x00\\xb9\\x00\\x85\\x00\\xe5\\x00\\x8f\\x00\\xb7\\x00\\x00\\x00'

正确的应该是长这样的:

1
'\\xe5\\x9b\\xbe\\xe5\\xb9\\x85\\xe5\\x8f\\xb7\\x00

以utf-8解码后对应的中文字符是”图幅号”

而英文字符返回的是这样的:

1
'B\\x00u\\x00i\\x00l\\x00d\\x00G\\x00e\\x00o\\x00C\\x00o\\x00d\\x00e\\x00\\x00'

仔细看,这串字符实际上就是”BuildGeoCode”,当然也是utf-8编码无疑。返回的编码以’\x00\x00’作为结束符,它是utf-16吗?它是utf-8吗?
这都算天坑了吧,没这样玩的。

SqlGetData则只有一个版本,无论locale为何都是返回utf-8编码的字符。

针对这几点问题制作了一个补丁,放在了github上,准备给原作者发一个pull request。修改后的版本,connect函数无论unicode_results为True或False都可以正确的返回中文字符。

还有一个函数SQLGetInfo(W),当使用SQL_DRIVER_NAME(值为6)调用时,无论调用哪个版本,都返回SQL_ERROR(值为-1)。

mdbtools
mdbtools是unixODBC上的mdb driver,当前只支持读操作,查询数据时尙不支持group by字句,select得到结果后自行排序吧。

UPDATE:
补丁已经迅速进入官方主线

===
[erq]