2011-05-04 113 views
3

我正在與Python(和Twisted)一起對抗Sybase SQL Anywhere 12數週,現在我甚至可以開始工作。pyodbc如何確定編碼?

剩下的只有一個煩惱:如果我使用自定義Python 2.7.1(這是部署平臺)在CentOS 5上運行腳本,我會得到我的結果爲UTF-8

如果我在Ubuntu盒子(Natty Narwhal)上運行它,我可以在latin1中獲得它們。不用說,我寧願用Unicode獲取所有數據,但這不是問題的關鍵。 :)

兩者都是64位盒子,都有自定義的Python 2.7.1。與UCS4和定製的unixODBC 2.3.0。

我在這裏不知所措。我找不到任何文件。是什麼讓pyodbc或unixODBC在兩個盒子上表現不同?

鐵的事實:

  • 的Python 2.7.1
  • DB:SQL Anywhere的12
  • 的unixODBC:2.3.0(2.2.14做相同的行爲),自與相同的標誌
  • 編譯
  • ODBC驅動程序:Sybase提供的原件。
  • CentOS 5給了我UTF-8,Ubuntu Natty Narwhal給了我latin1。

我ODBC.INI看起來是這樣的:

[sybase] 
Uid    = user 
Pwd    = password 
Driver   = /opt/sqlanywhere/lib64/libdbodbc12_r.so 
Threading  = True 
ServerName  = dbname 
CommLinks  = tcpip(host=the-host;DoBroadcast=None) 

我通過使用DNS = 'SYBASE' 只需連接。

TIA!

回答

4

我不能告訴你爲什麼它不同,但如果你在你的DSN中添加「Charset = utf-8」,你應該在兩臺機器上都得到你想要的結果。

聲明:我在SQL Anywhere工程中爲Sybase工作。

+0

謝謝!在那裏工作時,你能讓sqlanydb線程安全嗎? ;)( - > http://stackoverflow.com/questions/5790435/python-twisted-sqlanydb-abort/現在,我甚至崩潰與pyodbc,扭曲似乎觸發一些邪惡的司機) – hynek 2011-05-04 17:41:46

+5

那麼,我可以,但是午餐後我會做些什麼? – 2011-05-04 23:11:28

+4

那麼,你可以解決暫停問題,並休息一天休息? ;) – hynek 2011-05-05 07:25:22

4

pyodbc使用ODBC規範,它只支持2種編碼。以'W'結尾的所有ODBC函數都是使用SQLWCHAR的寬字符版本。這是由ODBC頭文件定義的,通常是UCS2,但有時候是UCS4。非寬版本使用SQLCHAR並且始終是(?)單字節ANSI/ASCII。

對於可變寬度編碼(如UTF8),ODBC絕對不支持。如果ODBC驅動程序提供,那絕對是不正確的。即使數據存儲在UTF8中,驅動程序也必須將其轉換爲ANSI或UCS2。不幸的是,大多數ODBC驅動程序完全不正確

發送到驅動程序時,如果數據是「unicode」對象,則pyodbc將使用ANSI,如果數據是'str'對象並且將使用UCS2/UCS4(無論SQLWCHAR定義在您的平臺上)。驅動程序在返回時確定數據是否爲SQLCHAR或SQLWCHAR,而pyodbc在此問題上沒有任何發言權。如果它是SQLCHAR,它將被轉換爲'str'對象,並且如果SQLWCHAR被轉換爲'unicode'對象。

這對於3.x版本稍有不同,它將默認將SQLCHAR & SQLWCHAR轉換爲Unicode。