Sqlite3.ProgrammingError: вы не должны использовать 8-битные байты, если не используете text_factory, который может интерпретировать 8-битные байты

Используя 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" и сжимаю через библиотеку zlib Python, я получаю вышеуказанное сообщение об ошибке. Я огляделся, но не смог найти простой ответ для этого.

Ответ 1

Если вы хотите использовать 8-битные строки вместо строки unicode в sqlite3, установите для text -factory подходящее соединение:

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

Ответ 2

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

Решение состоит в том, чтобы "отличить" значение как буфер "Python", например:

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

Надеюсь, это поможет кому-то еще.

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Синтаксис:

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