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ライブラリを使用して圧縮すると、上記のエラーメッセージが表示されます。
Sqlite3でUnicode文字列の代わりに8ビット文字列を使用する場合は、sqlite接続に適切なtext_factoryを設定します。
connection = sqlite3.connect(...)
connection.text_factory = str
解決策を見つけたので、検索にもう少し時間を費やすべきでした。
解決策は、値をPython 'buffer'のように 'キャスト'することです。
c.execute('insert or ignore into blah values (?, ?)',(cid, buffer(zlib.compress(html))))
これが他の人の助けになることを願っています。
BLOBタイプを使用するには、最初にzlib圧縮文字列をバイナリデータに変換する必要があります。そうしないと、sqliteはそれをテキスト文字列として処理しようとします。これはsqlite3.Binary()で行われます。例えば:
c.execute('insert or ignore into blah values (?, ?)',(cid,
sqlite3.Binary(zlib.compress(html))))
生の出力の代わりにrepr(html)を使用して値を保存し、使用する値を取得するときにeval(html)を使用できます。
c.execute('insert or ignore into blah values (?, ?)',(1, repr(zlib.compress(html))))
構文:
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]))