【问题标题】:pyodbc/FreeTDS/unixODBC on Debian Linux: issues with TDS VersionDebian Linux 上的 pyodbc/FreeTDS/unixODBC:TDS 版本的问题
【发布时间】:2012-01-17 06:11:20
【问题描述】:

我在 Debian Lenny (5.0.7) 上成功使用 pyodbc 时遇到了一些麻烦。具体来说,我似乎在获取 NVARCHAR 值时遇到了问题(不是 SQL Server 专家,所以请放轻松:))。

大多数传统查询都可以正常工作。例如,table1 中的行数产生

cursor.execute("SELECT count(id) from table1")
<pyodbc.Cursor object at 0xb7b9b170>
>>> cursor.fetchall()
[(27, )]

就像完整的 id 转储一样

>>> cursor.execute("SELECT id FROM table1")
<pyodbc.Cursor object at 0xb7b9b170>
>>> cursor.fetchall()
[(0.0, ), (3.0, ), (4.0, ), (5.0, ), (6.0, ), (7.0, ), (8.0, ), (11.0, ), (12.0, ), (18.0, ), (19.0, ), (20.0, ), (21.0, ), (22.0, ), (23.0, ), (24.0, ), (25.0, ), (26.0, ), (27.0, ), (28.0, ), (29.0, ), (32.0, ), (33.0, ), (34.0, ), (35.0, ), (36.0, ), (37.0, )]

但名称转储(同样,NVARCHAR 类型)不会

>>> cursor.execute("SELECT name FROM table1")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
pyodbc.ProgrammingError: ('42000', '[42000] [FreeTDS][SQL Server]Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier. (4004) (SQLExecDirectW)')

...关键错误是

pyodbc.ProgrammingError: ('42000', '[42000] [FreeTDS][SQL Server]无法使用 DB-Library(例如 ISQL ) 或 ODBC 版本 3.7 或更早版本。(4004) (SQLExecDirectW)')

这在表中是一致的。

我尝试了各种不同的版本,但现在我正在运行 unixODBC 2.2.11(来自 lenny repos)、FreeTDS 0.91(从源代码构建,使用 ./configure --enable-msdblib --with-tdsver=8.0)和 pyodbc 3.0.3(从源代码构建)。

使用类似的组合(unixODBC 2.3.0、FreeTDS 0.91、pyodbc 3.0.3),相同的代码可以在 Mac OS X 10.7.2 上运行。

我搜索了高低,研究了herehere 提出的解决方案,并重新编译了不同版本的 unixODBC 和 FreeTDS,但仍然没有骰子。相关配置文件如下:

user@host:~$ cat /usr/local/etc/freetds.conf
#$Id: freetds.conf,v 1.12 2007/12/25 06:02:36 jklowden Exp $
#
# This file is installed by FreeTDS if no file by the same 
# name is found in the installation directory.  
#
# For information about the layout of this file and its settings, 
# see the freetds.conf manpage "man freetds.conf".  

# Global settings are overridden by those in a database
# server specific section
[global]
        # TDS protocol version
        tds version = 8.0
        client charset = UTF-8

        # Whether to write a TDSDUMP file for diagnostic purposes
        # (setting this to /tmp is insecure on a multi-user system)
;       dump file = /tmp/freetds.log
;       debug flags = 0xffff

        # Command and connection timeouts
;       timeout = 10
;       connect timeout = 10

        # If you get out-of-memory errors, it may mean that your client
        # is trying to allocate a huge buffer for a TEXT field.  
        # Try setting 'text size' to a more reasonable limit 
        text size = 64512

# A typical Sybase server
[egServer50]
        host = symachine.domain.com
        port = 5000
        tds version = 5.0

# A typical Microsoft server
[egServer70]
        host = ntmachine.domain.com
        port = 1433
        tds version = 8.0

[foo]
        host = foo.bar.com
        port = 1433
        tds version = 8.0

user@host:~$ cat /etc/odbc.ini 
[foo]
Description     = Foo
Driver          = foobar
Trace           = No
Database        = db
Server          = foo.bar.com
Port            = 1433
TDS_Version     = 8.0
user@host:~$ cat /etc/odbcinst.ini 
[foobar]
Description     = Description
Driver          = /usr/lib/odbc/libtdsodbc.so
Setup           = /usr/lib/odbc/libtdsS.so
CPTimeout       =
CPReuse         =

非常感谢任何建议或指导!

【问题讨论】:

  • 我得到了同样的东西。在 mac 和 FreeBSD 上与 FreeTDS/unixODBC 一起工作,但在 CentOS 上不行

标签: sql-server-2008 pyodbc freetds unixodbc


【解决方案1】:

我在 Ubuntu 中遇到了同样的错误。我通过解决方法“解决”了它。 您需要做的就是设置环境变量TDSVER

import os
os.environ['TDSVER'] = '8.0'

正如我所说,这不是一个真正的“解决方案”,但它确实有效。

【讨论】:

  • 这是一个错字,还是真的是 TDSVER ?我猜是 TDSVER。
  • @Anoyz:它对我们的工作方式正是如此。但是,当使用不同的操作系统时,它可能是另一个环境变量。我们正在运行 ubuntu 服务器。
【解决方案2】:

尝试添加

TDS_Version=8.0;ClientCharset=UTF-8

在您的连接字符串中。

例如,

DRIVER=FreeTDS;SERVER=myserver;DATABASE=mydatebase;UID=me;PWD=pwd;TDS_Version=8.0;ClientCharset=UTF-8

【讨论】:

  • 谢谢,这是唯一对我有帮助的解决方案
  • 版本 8.0 仍由 FreeTDS 处理,仅出于兼容性考虑。请参阅:freetds.org/userguide/choosingtdsprotocol.htm我在 7.4 中使用了您的方法,效果很好。
【解决方案3】:

您不能绕过问题,将 name 转换或转换为它可以处理的东西吗?

cursor.execute("SELECT CAST(name AS TEXT) FROM table")

【讨论】:

  • 务实地说,是的,这就是我所做的。但该系统在不久的将来支持(并将大量处理)Unicode 数据。因此,我宁愿解决问题的根源,而不是无限期地投射
猜你喜欢
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 2014-09-21
  • 2011-02-05
  • 2014-12-31
  • 2014-12-09
相关资源
最近更新 更多