電子工作とPythonの技術ノート

設備監視CSVを途中で壊さない:Pythonの一時ファイルとos.replace

なぜ直接上書きしないのか

`open("equipment.csv", "w")` は既存の内容を切り詰めます。途中でセンサ取得に失敗したり、入力に不正値が見つかったりすると、半端なCSVが残り得ます。監視画面がそのCSVを読む場合、正常な前回のデータまで失う可能性があります。

代わりに、同じディレクトリに一時ファイルを作成し、全レコードを検証して書き終わってから `os.replace()` で置き換えます。Python公式資料では、POSIX上で成功した置換は原子的とされています。別ファイルシステム間では失敗し得るため、一時ファイルの作成先を対象と同じディレクトリにします。

実装

公開した atomic_csv_save.py に、Python標準ライブラリのみで動く `write_snapshot(path, records)` を収録しました。主要な処理は次のとおりです。


fd, temp_path = tempfile.mkstemp(dir=target.parent)

try:

    with os.fdopen(fd, "w", encoding="utf-8", newline="") as stream:

        writer = csv.writer(stream, lineterminator="\n")

        writer.writerow(["timestamp", "status"])

        # ここで各行を検証し、writer.writerow(...) で書き込む

        stream.flush()

        os.fsync(stream.fileno())

    os.replace(temp_path, target)

except BaseException:

    try:

        os.unlink(temp_path)

    except FileNotFoundError:

        pass

    raise

この抜粋は処理の概略です。実行する場合は検証を含む完全版コードを使用してください。テストコードも公開しています。完全版では入力日時をタイムゾーン付き `datetime` に限定し、状態を `RUNNING`、`STOPPED`、`UNKNOWN` の3種類に制限します。日時は秒精度で出力するため、ミリ秒が必要な場合は仕様変更が必要です。

動作確認

2026年10月18日、MacのPython 3.12で `python3 -m unittest discover -p 'test_atomic_csv_save.py' -v` を実行し、6件すべて成功しました。確認したのは新規保存、全件置換、不正な状態値、タイムゾーンなし日時、途中例外、空レコードです。エラー時に前回のCSVが残り、一時ファイルが削除されることも確認しました。

これは模擬データの単体テストであり、実PLCやネットワークドライブ、Windowsのファイルロック、電源断の試験ではありません。

実運用の注意

• `os.replace()` は既存ファイルを上書きします。バックアップや履歴が必要なら別途保存してください。

• 複数の書き手が同時に更新すると、最後の更新で前の内容が失われ得ます。単一ライターや排他制御が必要です。

• `flush()` と `os.fsync()` を行っても、親ディレクトリの同期やストレージの特性まで含む停電耐性は保証できません。

• 置換後のファイルの権限・所有者・ACLは旧ファイルと同一とは限りません。

• 入力件数の上限、時刻の単調増加、設備ID、ファイルサイズ上限などは別途検証してください。

• 既に開いている読み手は旧ファイルを読み続ける場合があります。更新を確認する際は開き直してください。

一次資料

• Python公式 `os.replace`:https://docs.python.org/3/library/os.html#os.replace

• Python公式 `os.fsync`:https://docs.python.org/3/library/os.html#os.fsync

• Python公式 `tempfile.mkstemp`:https://docs.python.org/3/library/tempfile.html#tempfile.mkstemp

• Python公式 `csv.writer`:https://docs.python.org/3/library/csv.html#csv.writer

関連記事(既公開):設備の稼働・停止を記録するCSVの設計(`csv-state-logging.html`)。

※コード抜粋は実装の概略です。動作環境や権限、同時書き込みには注意してください。

記事一覧へ戻る