2012-12-11 4 views
5

MSSQL 서버에서 유효한 문자열을 파이썬으로 가져올 수 없습니다. 어딘가에 인코딩 불일치가 있다고 생각합니다. 나는 그것이 tsql과 isql에서 읽기 가능한 결과를 얻을 수 있기 때문에 그것이 ODBC 계층과 파이썬 사이에 있다고 생각한다.freeTDS 및 unixODBC를 사용하여 SQL Server의 문자열을 올바르게 받아들이도록 pyodbc를 구성하는 방법은 무엇입니까?

pyodbc는 어떤 문자 인코딩을 기대합니까? 이 기능을 사용하려면 체인에서 무엇을 변경해야합니까?

#!/usr/bin/env python 
import pyodbc 

dsn = 'yourdb' 
user = 'import' 
password = 'get0lddata' 
database = 'YourDb' 

def get_cursor(): 
    con_string = 'DSN=%s;UID=%s;PWD=%s;DATABASE=%s;' % (dsn, user, password, database) 
    conn = pyodbc.connect(con_string) 
    return conn.cursor() 

if __name__ == '__main__': 
    c = get_cursor() 
    c.execute("select id, name from recipe where id = 4140567") 

    row = c.fetchone() 
    if row: 
     print row 

이 스크립트의 출력은 :

구체 예 다음

는 일례로서 간략화 파이썬 스크립트,

(Decimal('4140567'), u'\U0072006f\U006e0061\U00650067') 

대안 마지막 줄의 경우, 스크립트가 다음으로 변경됩니다.

,766,631,696,

그런 다음 결과는 다음과 같습니다

Traceback (most recent call last): 
    File "/home/mdenson/projects/test.py", line 20, in <module> 
    print "{0}, '{1}'".format(row.id, row.name) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) 

같은 쿼리 실행 TSQL을 사용하는 증명서 : isql을 에도

[email protected]:~# tsql -S cmw -U import -P get0lddata 
locale is "C" 
locale charset is "ANSI_X3.4-1968" 
using default charset "UTF-8" 
1> select id, name from recipe where id = 4140567 
2> go 
id  name 
4140567 orange2 
(1 row affected) 

과 : 그래서

[email protected]:~# isql -v yourdb import get0lddata 
SQL> select id, name from recipe where id = 4140567 
+----------------------+--------------------------+ 
| id     | name      | 
+----------------------+--------------------------+ 
| 4140567    | orange2     | 
+----------------------+--------------------------+ 
SQLRowCount returns 1 
1 rows fetched 

을 나는 아침에이 일을했다. 높고 낮게 보였고 어리 석다는 것을 알아 내지 못했습니다.

세부 여기

버전의 세부 사항은 다음과 같습니다

  • 클라이언트 우분투 12.04
  • FreeTDS를의 v0.91
  • 파이썬
  • 2.2.14 인 unixODBC입니다 2.7.3
  • pyodbc 2.1.7-1 (우분투 패키지에서)(소스에서 컴파일 된)3.0.7-beta06

  • 서버는 다음 클라이언트에서 몇 가지 구성 파일의 내용입니다 SQL Server Express에 2008 R2

와 XP입니다.

/etc/odbcinst.ini

[global] 
    tds version = 8.0 
    text size = 64512 
[cmw] 
    host = 192.168.90.104 
    port = 1433 
    tds version = 8.0 
    client charset = UTF-8 

[FreeTDS] 
Description = TDS driver (Sybase/MS SQL) 
Driver = /usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so 
Setup = /usr/lib/x86_64-linux-gnu/odbc/libtdsS.so 
CPTimeout = 
CPReuse = 
FileUsage = 1 

을/etc/ODBC를

/etc/freetds/freetds.conf.ini

[yourdb] 
Driver = FreeTDS 
Description = ODBC connection via FreeTDS 
Trace = No 
Servername = cmw 
Database = YourDB 
Charset = UTF-8 
+0

필자는이 작업을 계속하면서 pyodbc 3.0.7-beta06의 최신 버전을 컴파일했지만 동작에 변화가 없었습니다. – MatthewD

답변

2

계속 작업을 마친 지금 나는 파이썬으로 유니 코드 문자를 얻고 있습니다. 불행히도 내가 우연히 만난 해결책은 사촌에게 키스하는 것만 큼 만족 스럽습니다.

python3 및 python3-dev 패키지를 설치 한 다음 python3을 사용하여 pyodbc를 다시 빌드하여 문제를 해결했습니다.

이제는 파이썬 2.7에서 실행 중이지만 스크립트는 작동합니다.

이렇게하면 수정 된 사항을 알 수 없지만 이제는 작동하고 시작한 프로젝트로 이동할 수 있습니다.

+1

파이썬 버전이 아니라 우분투 패키지입니다. 데비안도 같은 문제가있었습니다. 나는 debian의 패키지를 제거하고'pip'를 통해 pyodbc를 설치했다. 모든 것이 잘 작동하고 파이썬 3은 필요하지 않다. –

1

혹시 BOM (Byte Order Marker)에 문제가 있습니까? 그렇다면, 어쩌면이 코드 조각은 도움이 될 것입니다 : 내가 this page에 그 조각을 발견

import codecs 
if s.beginswith(codecs.BOM_UTF8): 
    # The byte string s begins with the BOM: Do something. 
    # For example, decode the string as UTF-8 

if u[0] == unicode(codecs.BOM_UTF8, "utf8"): 
    # The unicode string begins with the BOM: Do something. 
    # For example, remove the character. 

# Strip the BOM from the beginning of the Unicode string, if it exists 
u.lstrip(unicode(codecs.BOM_UTF8, "utf8")) 

.

+0

흠. 귀하의 답변과 링크를 읽었으며 이것이 문제인지 또는 적어도 그 문제를 어떻게 처리해야할지 모르겠습니다. u '\ U0072006f \ U006e0061 \ U00650067'문자열에서 각각의 문자 쌍이 바뀌었지만 7 번째 문자가 누락되어 있으며 볼 수있는 BOM의 기호가 나타나지 않습니다. – MatthewD

+0

나는 실제로 "범위 내에 있지 않기 때문에 0-2 위치에있는 문자를 인코딩 할 수 없다"는 오류를 기반으로 문제를 찔렀다. 미안 매튜 –

0

pyodbc를 버전 3으로 업그레이드하면 문제가 해결됩니다.