sqlite3.ProgrammingError: Вы не должны использовать 8-битные строки байтов, если вы не используете text_factory, которая может интерпретировать 8-битные строки байтов - PullRequest
86 голосов
/ 06 августа 2010

Используя SQLite3 в Python, я пытаюсь сохранить сжатую версию фрагмента HTML-кода UTF-8.

Код выглядит так:

...
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)))

В какой момент вы получите ошибку:

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.

Если я использую «текст», а не «blob» и не сжимаю фрагмент HTML, все работает отлично (хотя db слишком большой) Когда я использую 'blob' и сжимаю с помощью библиотеки Python zlib, я получаю сообщение об ошибке выше. Я оглянулся, но не смог найти простой ответ на этот вопрос.

Ответы [ 5 ]

87 голосов
/ 26 октября 2010

Если вы хотите использовать 8-битные строки вместо строки Unicode в sqlite3, установите подходящее text_factory для подключения sqlite:

connection = sqlite3.connect(...)
connection.text_factory = str
35 голосов
/ 06 августа 2010

Найдя решение, я должен был потратить немного больше времени на поиск.

Решение - «преобразовать» значение в «буфер» Python, например:* Надеюсь, это поможет кому-то еще.

33 голосов
/ 09 июля 2014

Чтобы работать с типом BLOB, вы должны сначала преобразовать сжатую строку zlib в двоичные данные, иначе sqlite попытается обработать ее как текстовую строку.Это делается с помощью sqlite3.Binary ().Например:

c.execute('insert or ignore into blah values (?, ?)',(cid, 
sqlite3.Binary(zlib.compress(html))))
0 голосов
/ 02 декабря 2018

Синтаксис:

5 типов возможных хранилищ: NULL, INTEGER, TEXT, REAL и BLOB

BLOB обычно используется для хранения маринованных моделей или моделей с маринованным укропом

> 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 голосов
/ 07 июня 2013

Вы можете сохранить значение, используя repr (html) вместо необработанного вывода, а затем использовать eval (html) при получении значения для использования.

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