Ubuntu 9.04を使用しています
次のパッケージ バージョンをインストールしました。
unixodbc and unixodbc-dev: 2.2.11-16build3
tdsodbc: 0.82-4
libsybdb5: 0.82-4
freetds-common and freetds-dev: 0.82-4
私は次のように設定/etc/unixodbc.ini
しました:
[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/odbc/libtdsodbc.so
Setup = /usr/lib/odbc/libtdsS.so
CPTimeout =
CPReuse =
UsageCount = 2
私は次のように設定/etc/freetds/freetds.conf
しました:
[global]
tds version = 8.0
client charset = UTF-8
31e2fae4adbf1b2af1726e5668a3414cf46b454f
からpyodbc リビジョンを取得し、" "http://github.com/mkleehammer/pyodbc
を使用してインストールしましたpython setup.py install
ローカル ネットワークにMicrosoft SQL Server 2000がインストールされた Windows マシンがあり、ローカル IP アドレス 10.32.42.69 でリッスンしています。「Common」という名前で作成された空のデータベースがあります。完全な権限を持つパスワード「secret」を持つユーザー「sa」がいます。
次の python コードを使用して接続をセットアップしています。
import pyodbc
odbcstring = "SERVER=10.32.42.69;UID=sa;PWD=secret;DATABASE=Common;DRIVER=FreeTDS"
con = pyodbc.connect(s)
cur = con.cursor()
cur.execute('''
CREATE TABLE testing (
id INTEGER NOT NULL IDENTITY(1,1),
name NVARCHAR(200) NULL,
PRIMARY KEY (id)
)
''')
con.commit()
この時点まですべてが機能します。サーバーで SQLServer の Enterprise Manager を使用しましたが、新しいテーブルがそこにあります。ここで、テーブルにデータを挿入したいと思います。
cur = con.cursor()
cur.execute('INSERT INTO testing (name) VALUES (?)', (u'something',))
それは失敗します!! エラーは次のとおりです。
pyodbc.Error: ('HY004', '[HY004] [FreeTDS][SQL Server]Invalid data type
(0) (SQLBindParameter)'
クライアントは UTF-8 を使用するように構成されているため、データを UTF-8 にエンコードすることで解決できると考えました。それは機能しますが、奇妙なデータが返されます。
cur = con.cursor()
cur.execute('DELETE FROM testing')
cur.execute('INSERT INTO testing (name) VALUES (?)', (u'somé string'.encode('utf-8'),))
con.commit()
# fetching data back
cur = con.cursor()
cur.execute('SELECT name FROM testing')
data = cur.fetchone()
print type(data[0]), data[0]
エラーは発生しませんが、返されたデータは送信されたデータと同じではありません! 私は得る:
<type 'unicode'> somé string
つまり、pyodbc は Unicode オブジェクトを直接受け付けませんが、Unicode オブジェクトを返します! そしてエンコーディングが混同されています!
質問は次のとおりです。
NVARCHAR および/または NTEXT フィールドに Unicode データを挿入するコードが必要です。クエリを返すと、挿入したのと同じデータが必要になります。
これは、システムを別の方法で構成するか、挿入または取得時にデータを Unicode との間で正しく変換できるラッパー関数を使用することによって可能です。
それはあまり求めていませんよね?