pyodbc / FreeTDS / unixODBC в Debian Linux: проблемы с версией TDS - PullRequest
13 голосов
/ 17 января 2012

У меня проблемы с использованием pyodbc в Debian Lenny (5.0.7). В частности, мне кажется, что у меня возникают проблемы при получении значений NVARCHAR (не эксперт по SQL Server, поэтому будьте осторожны со мной :)).

Большинство традиционных запросов работают нормально. Например, количество строк в таблице1 дает

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

Как и полный дамп идентификаторов

>>> 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] Данные Unicode в сопоставлении только для Unicode или данные ntext не могут быть отправлены клиентам с использованием DB-Library (такой как ISQL ) или ODBC версии 3.7 или более ранней. (4004) (SQLExecDirectW) ')

Это согласованно для всех таблиц.

Я пробовал множество разных версий каждой из них, но сейчас я использую unixODBC 2.2.11 (из репозитория lenny), 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.

Я искал все выше и ниже, исследуя представленные решения здесь и здесь и перекомпилируя различные версии 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         =

Буду очень признателен за любые советы или указания!

Ответы [ 3 ]

10 голосов
/ 10 апреля 2014

Я столкнулся с той же ошибкой в ​​Ubuntu. Я «решил» это с обходом. Все, что вам нужно сделать, это установить переменную окружения TDSVER .

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

Как я уже сказал, это не настоящее "решение", но оно работает.

6 голосов
/ 20 августа 2017

Попробуйте добавить

TDS_Version=8.0;ClientCharset=UTF-8

в строку подключения.

Например,

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

1 голос
/ 15 февраля 2012

Не можете ли вы просто перешагнуть вопрос и либо преобразовать, либо привести name к чему-то, что он может обработать?

cursor.execute («ВЫБЕРИТЕ CAST (имя AS TEXT) ИЗ таблицы»)

...