2012-12-11 29 views
5

Geçerli bir dizeyi bir MSSQL sunucusundan python'a alamıyorum. Bir yerlerde kodlama uyuşmazlığı olduğuna inanıyorum. ODBC katmanı ve python arasında olduğuna inanıyorum çünkü tsql ve isql'de okunabilir sonuçlar alabiliyorum.FreeTDS ve unixODBC kullanarak SQL Server'dan dizeleri doğru olarak kabul etmek için pyodbc'yi nasıl yapılandırabilirim?

Pyodbc hangi karakter kodlamasını bekler? Bunu işe almak için zincirde değiştirmek için neye ihtiyacım var?

#!/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 

Bu senaryonun çıktı olan:

Özel Örnek Burada

, örnek olarak, basitleştirilmiş piton komut,

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

Alternatif olarak, son hattı ise komut dosyası aşağıdaki gibi değiştirilmiştir:

print "{0}, '{1}'".format(row.id, row.name) 

Sonra sonucudur:

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) 

aynı sorguyu yürütmek için TSQL kullanan bir transkript: isql da

[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) 

ve: Yani

[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 

Sabah bunun için çalıştım ve yüksek ve alçak görünüyordu ve neyin yanlış olduğunu anlayamadım.

Detaylar İşte

versiyon detayları aşağıdaki gibidir:

  • Müşteri Ubuntu 12.04
  • freetds v0.91
  • piton
  • 2.2.14 unixODBC olan 2.7.3
  • pyodbc 2.1.7-1 (ubuntu paketinden)(Kaynaktan derlenmiş)3.0.7-beta06

  • Sunucu Burada istemci üzerinde birkaç yapılandırma dosyalarının içeriği olan SQL Server Express 2008 R2

ile XP işletim sistemidir.

/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

Şu an devam eden çalışmamda, şimdi podbc'nin 3.0.7-beta06'nın en son sürümünü derledim, _but_ davranışta değişiklik yok. – MatthewD

cevap

2

Devam eden çalışmalardan sonra artık unicode karakterlerini python'a alıyorum. Ne yazık ki, tökezlediğim çözüm, kuzeninizi öpmek kadar tatmin edici.

Python3 ve python3-dev paketlerini yükleyip podhon ile podhon'u yeniden oluşturarak sorunu çözdüm3.

Şimdi bunu yaptım, şimdi hala benim python 2.7 ile çalıştırıyor olsam bile, komut dosyalarım çalışıyor.

Bunu yaparak neyin düzeltildiğini bilmiyorum, ancak şimdi çalışıyor ve başladığım projeye devam edebilirim.

+1

Python sürümü değil, ubuntu'nun paketi. Debian da aynı soruna sahipti. Debian'ın paketini kaldırdım ve pyodbc'yi "pip" ile kurdum ve her şey iyi çalışıyor, python 3 gerekli değil. –

1

BOM (Byte Order Marker) ile sorun yaşamanız olası mı? Eğer öyleyse, belki Bu kod ön yardımcı olacaktır: Ben this page o parçacık bulundu

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

Hmm. Cevabınızı ve bağlantıyı okudum ve sorunun bu olduğundan ya da en azından onunla nasıl bir şey yapacağımı bilmediğinden emin değilim. U '\ U0072006f \ U006e0061 \ U00650067' dizesinden, her bir çift harfin değiştirildiğini, ancak 7 karakterin eksik olduğunu ve görebileceğim bir BOM işareti olmadığını görürsünüz. – MatthewD

+0

Gerçekten sadece "menzil içinde olmadıkları için 0-2 konumlarındaki karakterleri kodlayamaz" diyerek hataya dayanarak problemi saptadım. Üzgünüm Matthew. –

0

Pyodbc'yi sürüm 3'e yükseltirseniz, sorun çözülecektir.