web-dev-qa-db-ja.com

sqlite3.ProgrammingError:8ビットバイト文字列を解釈できるtext_factoryを使用しない限り、8ビットバイト文字列を使用しないでください。

PythonでSQLite3を使用して、UTF-8 HTMLコードのスニペットの圧縮バージョンを保存しようとしています。

コードは次のようになります。

...
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」ではなく「text」を使用し、HTMLスニペットを圧縮しない場合、すべて正常に機能します(dbは大きすぎます)。 'blob'を使用してPython zlibライブラリを使用して圧縮すると、上記のエラーメッセージが表示されます。

86
R. Hill

Sqlite3でUnicode文字列の代わりに8ビット文字列を使用する場合は、sqlite接続に適切なtext_factoryを設定します。

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

解決策を見つけたので、検索にもう少し時間を費やすべきでした。

解決策は、値をPython 'buffer'のように 'キャスト'することです。

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

これが他の人の助けになることを願っています。

35
R. Hill

BLOBタイプを使用するには、最初にzlib圧縮文字列をバイナリデータに変換する必要があります。そうしないと、sqliteはそれをテキスト文字列として処理しようとします。これはsqlite3.Binary()で行われます。例えば:

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

生の出力の代わりにrepr(html)を使用して値を保存し、使用する値を取得するときにeval(html)を使用できます。

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

構文:

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
Pranzell