.odtドキュメントをSQLiteデータベースに挿入する単純なPythonスクリプトを作成しようとしています。これまでに行ったことは次のとおりですが、機能していないようです。
f=open('Loremipsum.odt', 'rb')
k=f.read()
f.close()
cursor.execute="INSERT INTO notes (note) VALUES ('%s')" %(sqlite.Binary(k))
cursor.close()
conn.close()
エラーメッセージは表示されませんが、レコードが挿入されていないことがわかります。私は何が間違っているのですか?また、保存されているドキュメントを抽出して戻すにはどうすればよいですか?ありがとう!
それが何であるかわからないsqlite.Binary
使用していますが、とにかく、これが実際の例です。
import sqlite3
# let's just make an arbitrary binary file...
with open('/tmp/abin', 'wb') as f:
f.write(''.join(chr(i) for i in range(55)))
# ...and read it back into a blob
with open('/tmp/abin', 'rb') as f:
ablob = f.read()
# OK, now for the DB part: we make it...:
db = sqlite3.connect('/tmp/thedb')
db.execute('CREATE TABLE t (thebin BLOB)')
db.execute('INSERT INTO t VALUES(?)', [buffer(ablob)])
db.commit()
db.close()
# ...and read it back:
db = sqlite3.connect('/tmp/thedb')
row = db.execute('SELECT * FROM t').fetchone()
print repr(str(row[0]))
Python 2.6で実行すると、このコードは、期待どおり、必要に応じて次のように表示されます。 '\ x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f! "#$%&\ '()* +、-。/ 0123456 '
ブロブを挿入するにはbuffer
を使用し、文字列として読み戻すにはstr
を使用する必要があることに注意してください(結果としてbuffer
タイプも使用するため)-ディスクに書き込むだけの場合は、後者のパッセージは必要ありません(ファイルのwrite
メソッドは文字列を受け入れるのと同じようにバッファオブジェクトを受け入れるため)。
与えられた例には複数の問題があります。それらを一つずつ取り上げていきます。
execute()
メソッドを実行しておらず、オブジェクトに文字列を割り当てています。 (Pythonでは、メソッドもオブジェクトです。)CREATE TABLE
_ステートメントがあったとすると、新しい暗黙のトランザクションが作成されます。また、データをデータベースファイルに保存するには、commit()
ステートメントを発行する必要があります。 SQLiteでは、SELECT
以外のステートメントは暗黙的なトランザクションを開始します。 (MySQLなどの一部のデータベースは、デフォルトで自動コミットモードになっています。これはSQLiteには当てはまりません。)これは、SQLiteデータベースのDocsテーブルにLibreOfficeドキュメントを書き込む適切な作業例です。
_#!/usr/bin/python
# -*- coding: utf-8 -*-
import sqlite3 as lite
fl = open('book.odt', 'rb')
with fl:
data = fl.read()
con = lite.connect('test.db')
with con:
cur = con.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS Docs(Data BLOB)")
sql = "INSERT INTO Docs(Data) VALUES (?)"
cur.execute(sql, (lite.Binary(data), ))
_
Book.odtファイルは、現在の作業ディレクトリにあります。 commit()メソッドを手動で呼び出さなかったのは、これが舞台裏でwithキーワードによって処理されるためです。
問題:
実行した完全なコードを表示しませんでした。回答者にsqlite.Binary(k)
のようなものを推測させてはいけません。
基本的な問題:トランザクションをコミットしませんでした。conn.commit()
の前にconn.close()
を使用してください。