web-dev-qa-db-fra.com

sqlite3.ProgrammingError: vous ne devez pas utiliser de chaînes d'octets de caractères 8 bits à moins d'utiliser un text_factory pouvant interpréter

En utilisant SQLite3 en Python, j'essaie de stocker une version compressée d'un extrait de code HTML UTF-8.

Le code ressemble à ceci:

...
c = connection.cursor()
c.execute('create table blah (cid integer primary key,html blob)')
...
c.execute('insert or ignore into blah values (?, ?)',(cid, zlib.compress(html)))

A quel point à obtenir l'erreur:

sqlite3.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

Si j'utilise 'texte' plutôt que 'blob' et que je ne compresse pas l'extrait de code HTML, tout fonctionne correctement (la base de données est trop grande cependant). Lorsque j'utilise 'blob' et que je compresse via la bibliothèque zlib Python, j'obtiens le message d'erreur ci-dessus. J'ai regardé autour de moi mais je n'ai pas trouvé de réponse simple à cette question.

85
R. Hill

Si vous souhaitez utiliser des chaînes 8 bits au lieu de chaînes Unicode dans sqlite3, définissez approptiate text_factory pour la connexion sqlite:

connection = sqlite3.connect(...)
connection.text_factory = str
87
zag

J'ai trouvé la solution, j'aurais dû passer un peu plus de temps à chercher.

La solution consiste à "transtyper" la valeur sous forme de "tampon" Python, comme suit:

c.execute('insert or ignore into blah values (?, ?)',(cid, buffer(zlib.compress(html))))

J'espère que cela aidera quelqu'un d'autre.

35
R. Hill

Pour pouvoir utiliser le type BLOB, vous devez d’abord convertir votre chaîne compressée zlib en données binaires - sinon, SQLite essaiera de la traiter comme une chaîne de texte. Ceci est fait avec sqlite3.Binary (). Par exemple:

c.execute('insert or ignore into blah values (?, ?)',(cid, 
sqlite3.Binary(zlib.compress(html))))
32
MarioVilas

Vous pouvez stocker la valeur en utilisant repr (html) à la place de la sortie brute, puis utiliser eval (html) lors de la récupération de la valeur à utiliser.

c.execute('insert or ignore into blah values (?, ?)',(1, repr(zlib.compress(html))))
0
zwalker

Syntaxe:

5 types de stockage possibles: NULL, INTEGER, TEXT, REAL et BLOB

BLOB est généralement utilisé pour stocker des modèles marinés ou des modèles marinés à l'aneth

> cur.execute('''INSERT INTO Tablename(Col1, Col2, Col3, Col4) VALUES(?,?,?,?)''', 
                                      [TextValue, Real_Value, Buffer(model), sqlite3.Binary(model2)])
> conn.commit()

> # Read Data:
> df = pd.read_sql('SELECT * FROM Model, con=conn) 
> model1 = str(df['Col3'].values[0]))
> model2 = str(df['Col'].values[0]))
0
Pranzell