MENU

SQLiteを読み取り専用で開く|空の台帳を作らない

当ページのリンクには広告(PR)が含まれていることがあります。
SQLiteを読み取り専用で開く|空の台帳を作らない。台帳のパス、読み取り専用、既存DBを確認の処理例。

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日に確認しました。

この記事を書いた人

Watanabeのアバター Watanabe サイト運営者

2020年よりブログ開始。
SEOが思いのほか性にあっていたようで現在に至る。
モットーは「勝率の高い選択をする」
AIは活用するが吉、最後は人間が息を吹き込む。
アートと科学を追求し、日々精進。
―――
収益:6~7桁をウゴウゴ。
サイト:ペラサイト~中規模サイトまで運営中。
案件:1000円以上の案件をメインに取組中。
打ち手:ブラックSEO~ホワイトSEOまで
―――

目次