Gå til innhold

[Python] Problemer med mysqldb og blob


Anbefalte innlegg

Hei

 

Får en feilmelding, tror jeg vet hva feilen er, men klarer ikke google etter rett svar...

 

Jeg har en variabel i form av et array, dette skal så settes inn som en blob i en mysql-database

 

userid = 1

var1 = {'tuple1': ('one', 'two', 'three'), 'tuple2': ('one', 'two', 'three')}

data = cPickle.dumps(variable)

 

sql= "UPDATE cache SET ablob = %s WHERE user_id = %s"

 

conn = self.conn

cursor = conn.cursor()

cursor.execute(sql, (data, userid))

conn.commit()

cursor.close()

 

Får feilmelding <class '_mysql_exceptions.InterfaceError'>

 

/usr/lib/pymodules/python2.6/MySQLdb/cursors.py in execute(....)

 

145 del self.messages[:]

146 db = self._get_db()

147 charset = db.character_set_name()

148 if isinstance(query, unicode):

149 query = query.encode(charset)

charset undefined, db = <weakproxy at 0x9fd220c to Connection at 0x9f7119c>, db.character_set_name = <built-in method character_set_name of Connection object at 0x9f7119c>

 

Jeg tror at feilen er relatert til %s i sql-strengen og at feilmeldingen skyldes at python forsøker å tolke data-variabelen som en streng - men hva bør jeg ha istedenfor %s som en binær variabel?

 

Eller er jeg helt på viddene?

 

/Endre

Lenke til kommentar
Videoannonse
Annonse

Tror du må ha det i dette formatet VALUES (%s, %s)

 

Et eksempel fra python cookbook.

import MySQLdb, cPickle
# Connect to a DB, e.g., the test DB on your localhost, and get a cursor
connection = MySQLdb.connect(db="test")
cursor = connection.cursor( )
# Make a new table for experimentation
cursor.execute("CREATE TABLE justatest (name TEXT, ablob BLOB)")
try:
   # Prepare some BLOBs to insert in the table
   names = 'aramis', 'athos', 'porthos'
   data = { }
   for name in names:
       datum = list(name)
       datum.sort( )
       data[name] = cPickle.dumps(datum, 2)
   # Perform the insertions
   sql = "INSERT INTO justatest VALUES(%s, %s)"
   for name in names:
       cursor.execute(sql, (name, MySQLdb.escape_string(data[name])) )
   # Recover the data so you can check back
   sql = "SELECT name, ablob FROM justatest ORDER BY name"
   cursor.execute(sql)
   for name, blob in cursor.fetchall( ):
       print name, cPickle.loads(blob), cPickle.loads(data[name])
finally:
   # Done. Remove the table and close the connection.
   cursor.execute("DROP TABLE justatest")
   connection.close( )

 

Nyere versjon MySQLdb.

sql = "INSERT INTO sometable (col1, col2) VALUES (%s, %s)"
cursor.execute(sql, (val1, val2))

 

Eldere versjon av MySQLdb,må ha med escape_string().

sql = "INSERT INTO sometable (col1, col2) VALUES (%s, %s)"
cursor.execute(sql, (MySQLdb.escape_string(val1),  MySQLdb.escape_string(val2))

Lenke til kommentar

 

147 charset = db.character_set_name()

148 if isinstance(query, unicode):

149 query = query.encode(charset)

charset undefined, db = <weakproxy at 0x9fd220c to Connection at 0x9f7119c>, db.character_set_name = <built-in method character_set_name of Connection object at 0x9f7119c>

 

 

Python DB interfacen burde escape dataene dine, men det ser ut som om den forsøker å tolke det som et gitt karaktersett, noen den ikke burde gjøre for en blob (pickle dataene ser jo ganske hårete ut med masse ', men den burde escape det når du bruker values(%s)).

 

Jeg bruker helst PostgreSQL så jeg er ikke så kjent med hvordan mysql håndterer dette med blob og karaktersett og i hvilken grad Python blander seg opp i dette, spesielt hvis du gjør en update av både en vanlig streng og en blob i samme query.

 

Hvorfor vil du forresten lagre pickle dataene i databasen din? Det kan fort oppstå problemer på kryss av python versjoner, 32-bit, 64-bit, (kanskje også big/little endian). Er det ikke mulig å lagre data fra klassene?

Lenke til kommentar

Jeg kan ikke se noe feil med spørringen din, bortsett fra at "variable" i cPickle.dumps(variable) sikkert skal være "var1".

 

Jeg tror kanskje det kan være at MySQLdb er kompilert mot feil versjon av mysql. Prøv å rekompiler MySQLdb og se om det hjelper.

Endret av FraXinuS
Lenke til kommentar

Jeg har rullet tilbake en gammel versjon, der funker

 

data = cPickle.dumps(results)

sql_2 = """INSERT INTO cache (user_id, resultblob) VALUES (%s, %s)"""

cursor.execute(sql_2, (userid, data))

 

og

 

data = cPickle.dumps(names)

sql = """UPDATE stored_names SET nameblob = %s WHERE user_id = %s"""

cursor.execute(sql, (data, userid))

 

helt fint. Så det er en eller annen feil i mine siste endringer som medfører denne feilmeldingen, dessverre skjønner jeg den ikke helt. Men jeg skal teste litt videre...

 

Takk for kommentarer så langt!

 

/Endre

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...