SQLite (/ˌɛsˌkjuːˌɛlˈaɪt/, /ˈsiːkwəˌlaɪt/) は、パブリックドメインの軽量なリレーショナルデータベース管理システム (RDBMS) です。他の多くのデータベース管理システムとは対照的に、サーバとしてではなくアプリケーションに組み込んで利用するデータベースです。 一般的な RDBMS と違い、API は単純にライブラリを呼び出すだけであり、データの保存に単一のファイルを使用することが特徴でです。
SQLite のデータベースでバイナリーデータを扱うケースを、Qt for Python (Pyside2) の GUI で、PDF ファイルを選んで読み込んだ内容をデータベースに格納し、それを外部プログラムで開く、というサンプルを作って確認しましたので、備忘録にしました。
本ブログ記事では下記の OS 環境で動作確認をしています。
| Fedora 33 (Workstation Edition) | x86_64 |
以下に、サンプル sqlite_binary_test.py を示しました。
サンプルを実行して、メニューから File(F) » Open をクリックします。
SQLite のデータベースファイル self.dbname (= 'test.sqlite') が存在しなければ、カレントディレクトリに作成します。
def initDB(self):
init_query = [
'CREATE TABLE file (name_file TEXT UNIQUE, content NONE)',
]
con = sqlite3.connect(self.dbname)
cur = con.cursor()
for query in init_query:
cur.execute(query)
con.commit()
con.close()
データベースに書き込む PDF ファイルを選択します。
ファイルをバイナリモードで読み込んでパスを除いたファイル名と、読み込んだバイナリをデータベースに書き込みます。
def showDialog(self, combo: QComboBox):
dialog = QFileDialog()
dialog.setNameFilters(['PDF files (*.pdf)'])
if dialog.exec_():
fname = dialog.selectedFiles()[0]
name_file = os.path.basename(fname)
f = open(fname, 'rb')
with f:
content = f.read()
con = sqlite3.connect(self.dbname)
cur = con.cursor()
cur.execute("INSERT INTO file VALUES(?, ?);", [name_file, content])
con.commit()
con.close()
self.get_filelist(combo)
コンボボックスに読み込んだファイルが追加されるので、 Open ボタンをクリックします。
コンボボックスに表示されているファイル名と一致するレコードのバイナリの内容を読み込んで、一時保存領域にファイル名で保存して、デフォルトのアプリケーションでファイルを開きます。
def on_click_open(self, combo: QComboBox):
name_file = combo.currentText()
if len(name_file) == 0:
return
out_file = os.path.join(tempfile.gettempdir(), name_file)
con = sqlite3.connect(self.dbname)
cur = con.cursor()
cur.execute("SELECT content FROM file WHERE name_file = ?;", [name_file])
out = cur.fetchall()
con.close()
with open(out_file, 'wb') as f:
f.write(out[0][0])
if platform.system() == 'Linux':
subprocess.Popen(['xdg-open', out_file])
elif platform.system() == 'Darwin':
subprocess.Popen(['open', out_file])
else:
os.startfile(out_file)
GNOME のドキュメントビューア Evince が起動し、PDF の内容が表示されます。
動作確認をする目的で作成したサンプルであるため、無駄な重複が残っていますしエラー時の例外処理などもしていません。なお、今回扱った PDF ファイルは圧縮されているので、Python 側で更に圧縮する処理は加えていませんが、扱うバイナリファイルの内容により検討する必要があります。
参考サイト







0 件のコメント:
コメントを投稿