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
python2.6-dev
私は次のように設定/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
text size = 4294967295
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(odbcstring)
cur = con.cursor()
cur.execute("""
IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'testing')
DROP TABLE testing
""")
cur.execute('''
CREATE TABLE testing (
id INTEGER NOT NULL IDENTITY(1,1),
myimage IMAGE NULL,
PRIMARY KEY (id)
)
''')
con.commit()
この時点まですべてが機能します。サーバーで SQLServer の Enterprise Manager を使用しましたが、新しいテーブルがそこにあります。ここで、テーブルにデータを挿入したいと思います。
cur = con.cursor()
# using web data for exact reproduction of the error by all.
# I'm actually reading a local file in my real code.
url = 'http://www.forestwander.com/wp-content/original/2009_02/west-virginia-mountains.jpg'
data = urllib2.urlopen(url).read()
sql = "INSERT INTO testing (myimage) VALUES (?)"
ここで私の元の質問で、使用に問題がありcur.execute(sql, (data,))
ましたが、質問を編集しました。以下のVinay Sajipの回答(ありがとう)に従って、次のように変更したためです。
cur.execute(sql, (pyodbc.Binary(data),))
con.commit()
そして挿入は完璧に機能しています。次のテスト コードを使用して、挿入されたデータのサイズを確認できます。
cur.execute('SELECT DATALENGTH(myimage) FROM testing WHERE id = 1')
data_inside = cur.fetchone()[0]
assert data_inside == len(data)
これは完全に合格します!!!
ここでの問題は、データを取り戻すことです。
私は一般的なアプローチを試みています:
cur.execute('SELECT myimage FROM testing WHERE id = 1')
result = cur.fetchone()
returned_data = str(result[0]) # transforming buffer object
print 'Original: %d; Returned: %d' % (len(data), len(returned_data))
assert data == returned_data
しかし、それは失敗します!!
Original: 4744611; Returned: 4096
Traceback (most recent call last):
File "/home/nosklo/devel/teste_mssql_pyodbc_unicode.py", line 53, in <module>
assert data == returned_data
AssertionError
上記のすべてのコードをここに1 つのファイルにまとめました。これにより、支援したい人が簡単にテストできるようになります。
質問は次のとおりです。
画像ファイルを mssql に挿入する Python コードが必要です。画像をクエリしてユーザーに表示したい。
mssql の列の型は気にしません。この例では " " 列タイプを使用してIMAGE
いますが、元の状態で挿入したファイルのバイナリ データを取得する限り、任意のバイナリ/ブロブ タイプで使用できます。Vinay Sajip は、SQL SERVER 2000 でこれが推奨されるデータ型であると以下で述べています。
データはエラーなしで挿入されていますが、データを取得すると 4k しか返されません。(データは 4096 で切り捨てられます)。
どうすればそれを機能させることができますか?
編集: 以下の Vinay Sajip の回答は、フィールドで pyodbc.Binary を使用するためのヒントを与えてくれました。それに応じて質問を更新しました。ありがとうビナイ・サジプ!
Alex Martelli のコメントから、DATALENGTH
MS SQL 関数を使用して、データが列に完全にロードされているかどうかをテストするというアイデアが得られました。ありがとうアレックス・マーテリ!