SQLiteの台帳を読むつもりが場所の間違いで空のDBを新しく作ってしまうことがあります。通常の接続は、指定したファイルがなければ作成するためです。空の結果を見て「台帳にデータがない」と判断すると、元の台帳とは別のファイルを調べている可能性があります。
レポートや点検で読み込みだけが必要なら、mode=roで既存DBを読み取り専用に開く方法があります。存在しない場所は失敗となり、接続先で書き込みも行えません。
一時DBで読み取り専用を試す
次は練習用の一時フォルダーにDBを作り、接続し直す例です。利用者の既存DBは開きません。Path.as_uriでパスをfile URIへ変え、uri=Trueを付けて渡します。
import sqlite3
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "practice.sqlite3"
writer = sqlite3.connect(path)
try:
writer.execute("CREATE TABLE tickets (id TEXT PRIMARY KEY)")
writer.execute("INSERT INTO tickets VALUES (?)", ("T1",))
writer.commit()
finally:
writer.close()
reader = sqlite3.connect(path.as_uri() + "?mode=ro", uri=True)
try:
print("読み取ったID:", reader.execute("SELECT id FROM tickets").fetchone()[0])
try:
reader.execute("INSERT INTO tickets VALUES (?)", ("T2",))
except sqlite3.OperationalError:
print("書込みは拒否")
else:
raise AssertionError("書込みが通りました")
finally:
reader.close()
missing = Path(directory) / "missing.sqlite3"
try:
connection = sqlite3.connect(missing.as_uri() + "?mode=ro", uri=True)
except sqlite3.OperationalError:
print("存在しないDBは拒否")
else:
connection.close()
raise AssertionError("存在しないDBを開けました")
print("空のDBが作られていない:", not missing.exists())
assert not missing.exists()
T1は読めますが、書き込みと存在しないDBへの接続は拒否されます。Windows・Python 3.12.10・SQLite 3.49.1で、この架空DBの動作を確認しました。
実ファイルへ適用する場合は、確認した絶対パスへ置き換えます。file:とパスを手でつなぐより、as_uriを使うと、パスに含まれる文字をURIとして扱う部分を任せられます。
読めたDBが目的の台帳か確かめる
読み取り専用で開けても、そのファイルが目的の台帳かどうかまでは分かりません。必要なテーブルと列があるか、想定する期間や件数のデータかを確認します。
相対パスは実行場所によって参照先が変わります。タスク実行などで作業フォルダーが違う場合は、コードが使う基準パスを明確にしてください。接続エラーを空配列へ置き換えて成功として続けると、取得できなかった状態とゼロ件を区別できなくなります。
読み取り専用と情報共有は別
mode=roはこの接続での書き込みを制限する指定です。DBの内容を誰が読めるかを決めたり、ファイルを暗号化したりする設定ではありません。DBのコピーや出力したレポートの共有範囲は別に管理します。
また、closeはトランザクションのwithブロックとは別の処理です。読み取りだけの小さなツールでも、接続を閉じる場所を明確にします。例のようにfinallyへ置くと、途中で例外が出た場合にも閉じる形にできます。
基本的な検索はSQLite入門、実行場所とパスの関係はpathlib入門で確認できます。
参考資料
Python sqlite3とSQLite URIの公式資料を2026年11月1日に確認しました。
