【问题标题】:How does pyodbc determine the encoding?pyodbc 如何确定编码?
【发布时间】:2011-05-04 13:53:51
【问题描述】:

到目前为止,我已经将 Sybase SQL Anywhere 12 与 Python(和 Twisted)一起使用了几个星期,我什至让我的东西正常工作了。

只剩下一个烦恼:如果我在 CentOS 5 上使用自定义 Python 2.7.1(这是部署平台)运行我的脚本,我得到的结果是 UTF-8

如果我在我的 Ubuntu 机器 (Natty Narwhal) 上运行它,我会在 latin1 中获得它们。

不用说,我更愿意以 Unicode 格式获取我的所有数据,但这不是这个问题的重点。 :)

两者都是 64 位盒子,都有自定义 Python 2.7.1。使用 UCS4 和自定义构建的 unixODBC 2.3.0。

我在这里不知所措。我找不到任何文档。是什么让 pyodbc 或 unixODBC 在这两个盒子上表现不同?

确凿的事实:

  • Python:2.7.1
  • 数据库: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!

【问题讨论】:

    标签: python pyodbc sqlanywhere unixodbc


    【解决方案1】:

    我无法告诉你为什么不同,但如果你将“Charset=utf-8”添加到你的 DSN,你应该在两台机器上都得到你想要的结果。

    免责声明:我在 Sybase 从事 SQL Anywhere 工程工作。

    【讨论】:

    • 谢谢!在那里工作时,你能让 sqlanydb 线程安全吗? ;) (-> stackoverflow.com/questions/5790435/… 到现在为止,我什至用 pyodbc 崩溃了,扭曲似乎会在你的驱动程序中触发一些邪恶的东西)
    • 好吧,我可以,但是我午餐后会做什么?
    • 嗯,您可以解决停机问题并休息一天吗? ;)
    【解决方案2】:

    pyodbc 使用 ODBC 规范,它只支持 2 种编码。所有以“W”结尾的 ODBC 函数都是使用 SQLWCHAR 的宽字符版本。这由 ODBC 标头定义,通常为 UCS2,但偶尔为 UCS4。非宽版本使用 SQLCHAR 并且总是(?)单字节 ANSI/ASCII。

    在 ODBC 中绝对不支持可变宽度编码,例如 UTF8。如果 ODBC 驱动程序提供了它,那是绝对不正确的。即使数据以 UTF8 存储,也必须由驱动程序将其转换为 ANSI 或 UCS2。不幸的是,大多数 ODBC 驱动程序完全不正确。

    当发送到驱动程序时,如果数据是“str”对象,pyodbc 将使用 ANSI;如果数据是“unicode”对象,pyodbc 将使用 UCS2/UCS4(无论 SQLWCHAR 在您的平台上定义什么)。驱动程序在返回数据时确定数据是 SQLCHAR 还是 SQLWCHAR,pyodbc 对此没有任何发言权。如果是 SQLCHAR,则转换为 'str' 对象,如果 SQLWCHAR 转换为 'unicode' 对象。

    这对于 3.x 版本会略有不同,默认情况下会将 SQLCHAR 和 SQLWCHAR 都转换为 Unicode。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-16
      • 2011-03-13
      • 2017-07-15
      • 2011-10-05
      • 2010-09-30
      相关资源
      最近更新 更多