Python 業務自動化 | ファイル・フォルダ自動化:基本操作 - バックアップ世代管理

Python Python
スポンサーリンク

バックアップ世代管理は「古いバックアップを自動で整理し、必要な世代だけ残す」ための仕組み

バックアップは作るだけでは不十分で、古いバックアップをどう扱うかが非常に重要です。
バックアップが増え続けると、ディスク容量を圧迫し、最悪の場合システム停止につながります。
そこで必要になるのが バックアップ世代管理(ローテーション) です。

Python では、フォルダ名やファイル名に付けた日付・番号をもとに、
「新しい順に並べる → 古いものを削除する」という流れを自動化できます。


バックアップ世代管理の基本構造

バックアップ世代管理は次の3ステップで構成されます。

  1. バックアップフォルダ内のバックアップ一覧を取得
  2. 新しい順に並べ替える
  3. 指定した世代数を超えたものを削除する

この流れを理解すると、どんな形式のバックアップでも管理できるようになります。


日付フォルダを使った世代管理の基本テンプレート

日付フォルダの例

backup/
 ├── 2024-03-01/
 ├── 2024-03-02/
 ├── 2024-03-03/
 └── 2024-03-04/

コード例:最新3世代だけ残す

import os
import shutil
from datetime import datetime

backup_root = "backup"
keep = 3  # 残す世代数

folders = []

for name in os.listdir(backup_root):
    path = os.path.join(backup_root, name)
    if os.path.isdir(path):
        try:
            dt = datetime.strptime(name, "%Y-%m-%d")
            folders.append((dt, path))
        except ValueError:
            pass

folders.sort(reverse=True, key=lambda x: x[0])

for dt, path in folders[keep:]:
    shutil.rmtree(path)
    print("削除:", path)
Python

深掘りポイント

  • フォルダ名を日付として datetime.strptime() で解析する
  • 日付として解釈できないフォルダは無視する
  • 新しい順に並べて、残す世代以外を削除する
  • shutil.rmtree() はフォルダごと削除するため強力(慎重に扱う)

タイムスタンプ付きバックアップの世代管理

バックアップ名の例

project_20240301_120000.zip
project_20240302_120000.zip
project_20240303_120000.zip

コード例:ファイル名から日付を抽出して管理

import os
import re
import shutil
from datetime import datetime

backup_root = "backup"
keep = 5

pattern = re.compile(r".*_(\d{8}_\d{6})\.zip$")

files = []

for name in os.listdir(backup_root):
    path = os.path.join(backup_root, name)
    if os.path.isfile(path):
        m = pattern.match(name)
        if m:
            dt = datetime.strptime(m.group(1), "%Y%m%d_%H%M%S")
            files.append((dt, path))

files.sort(reverse=True, key=lambda x: x[0])

for dt, path in files[keep:]:
    os.remove(path)
    print("削除:", path)
Python

深掘りポイント

  • 正規表現で日付部分を抽出
  • タイムスタンプ形式(YYYYMMDD_HHMMSS)はソートに強い
  • ファイル単体のバックアップ管理に最適

更新日時を使った世代管理(名前に日付がない場合)

シナリオ

バックアップファイル名に日付が入っていない場合でも、更新日時で管理できる。

import os
import shutil

backup_root = "backup"
keep = 3

files = []

for name in os.listdir(backup_root):
    path = os.path.join(backup_root, name)
    if os.path.isfile(path):
        ts = os.path.getmtime(path)
        files.append((ts, path))

files.sort(reverse=True, key=lambda x: x[0])

for ts, path in files[keep:]:
    os.remove(path)
    print("削除:", path)
Python

深掘りポイント

  • 更新日時(mtime)は「いつ作られたか」の代用として使える
  • 名前に日付がないバックアップでも管理可能
  • OS によっては作成日時より更新日時の方が安定している

フォルダ丸ごとのバックアップ+世代管理テンプレート

シナリオ

project フォルダを毎回コピーし、最新5世代だけ残したい。

import os
import shutil
from datetime import datetime

src = "project"
backup_root = "backup"
os.makedirs(backup_root, exist_ok=True)

timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
dst = os.path.join(backup_root, f"project_{timestamp}")

shutil.copytree(src, dst)
print("バックアップ作成:", dst)

folders = sorted(
    [os.path.join(backup_root, d) for d in os.listdir(backup_root)],
    key=os.path.getmtime,
    reverse=True
)

keep = 5

for path in folders[keep:]:
    shutil.rmtree(path)
    print("削除:", path)
Python

深掘りポイント

  • copytree でフォルダ丸ごとバックアップ
  • バックアップフォルダを更新日時でソート
  • 最新5世代だけ残す
  • これだけで「作成 → 整理」まで自動化できる

pathlib を使った読みやすい世代管理

Path.glob と stat を使う

from pathlib import Path
import shutil

backup_root = Path("backup")
keep = 3

folders = sorted(
    [p for p in backup_root.iterdir() if p.is_dir()],
    key=lambda p: p.stat().st_mtime,
    reverse=True
)

for p in folders[keep:]:
    shutil.rmtree(p)
    print("削除:", p)
Python

メリット

  • Path オブジェクトは読みやすく、パス操作が直感的
  • stat().st_mtime で更新日時を取得

バックアップ世代管理を安全に行うための考え方

  • 削除対象を決める前に 必ず一覧を表示して確認
  • バックアップ名に日付や番号を入れると管理が圧倒的に楽
  • 削除処理は慎重に扱う(特に rmtree は強力)
  • 世代数は業務要件に合わせて決める(3世代・5世代・7世代など)
  • ログを残すとトラブル時の調査が容易になる

バックアップ世代管理は、バックアップ作成とセットで考えることで、
「作る → 溜まる → 圧迫する → 整理する」という流れを完全に自動化できます。

タイトルとURLをコピーしました