Sto usando Ubuntu 9.04utilizzando pyodbc su Ubuntu per inserire un campo di immagine su SQL Server
Ho installato le seguenti versioni del pacchetto:
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
Ho configurato /etc/unixodbc.ini
come questo:
[FreeTDS]
Description = TDS driver (Sybase/MS SQL)
Driver = /usr/lib/odbc/libtdsodbc.so
Setup = /usr/lib/odbc/libtdsS.so
CPTimeout =
CPReuse =
UsageCount = 2
ho configurato /etc/freetds/freetds.conf
come questo:
[global]
tds version = 8.0
client charset = UTF-8
text size = 4294967295
ho afferrato revisione pyodbc 31e2fae4adbf1b2af1726e5668a3414cf46b454f
da http://github.com/mkleehammer/pyodbc
e installato tramite "python setup.py install
"
Ho una macchina Windows con Microsoft SQL Server 2000 installato sulla mia rete locale, e ascoltando sul IP locale indirizzo 10.32.42.69. Ho un database vuoto creato con il nome "Comune". Ho l'utente "sa" con password "secret" con tutti i privilegi.
Sto usando il seguente codice Python per impostare la connessione:
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()
Tutto WORKS fino a questo punto. Ho usato Enterprise Manager di SQLServer sul server e la nuova tabella è lì. Ora voglio inserire alcuni dati sul tavolo.
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 (?)"
Ora qui sulla mia domanda iniziale, ho avuto problemi con l'uso cur.execute(sql, (data,))
ma ora ho curato la questione, perché in seguito la risposta di Vinay Sajip sotto (Grazie), io che ho cambiato a:
cur.execute(sql, (pyodbc.Binary(data),))
con.commit()
E l'inserimento funziona perfettamente. Posso confermare la dimensione dei dati inseriti utilizzando il seguente codice di prova:
cur.execute('SELECT DATALENGTH(myimage) FROM testing WHERE id = 1')
data_inside = cur.fetchone()[0]
assert data_inside == len(data)
Che passa perfettamente !!!
Ora il problema riguarda il recupero dei dati.
Sto cercando l'approccio comune:
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
Tuttavia che non riesce !!
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
ho messo tutto il codice di cui sopra in un unico file here, per una facile verifica di tutti coloro che vogliono aiutare.
Ora per la domanda:
Voglio codice Python per inserire un file di immagine in mssql. Voglio interrogare l'immagine e mostrarla all'utente.
Non mi interessa il tipo di colonna in mssql.Sto usando il tipo di colonna "IMAGE
" nell'esempio, ma qualsiasi tipo di binario/blob farebbe, a patto che ottenga i dati binari per il file che ho inserito di nuovo non rinchiuso. Vinay Sajip ha dichiarato che questo è il tipo di dati preferito per questo in SQL SERVER 2000.
I dati vengono ora inseriti senza errori, tuttavia quando recupero i dati, vengono restituiti solo 4k. (I dati sono troncati su 4096).
Come posso farlo funzionare?
modifiche: la risposta di Vinay Sajip seguito mi ha dato un suggerimento per utilizzare pyodbc.Binary sul campo. Ho aggiornato la domanda di conseguenza. Grazie Vinay Sajip! Il commento di
Alex Martelli mi ha dato l'idea di utilizzare la funzione di DATALENGTH
MS SQL per verificare se i dati è a pieno carico sulla colonna. Grazie Alex Martelli!
cosa ottieni quando SELEZIONA DATALENGTH (myimage) DA testare? Almeno questo ti dirà se il tuo problema è con la memorizzazione o il recupero. –