Files
baiyue-logistics-chat/scripts/db_maintenance.py
T
2026-11-02 17:51:10 +08:00

55 lines
2.3 KiB
Python

"""Database backup/check/list and explicitly offline restore; no app initialization."""
import argparse
import json
from pathlib import Path
import sqlite3
import sys
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from logistics_chat.database_backup import (check_database, daily_backup, restore_database,
snapshot_database, unique_backup_path)
def main(argv=None):
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--db', type=Path, default=ROOT/'history.db')
parser.add_argument('--backup-dir', type=Path, default=None)
parser.add_argument('command', choices=('backup', 'daily', 'list', 'check', 'restore'))
parser.add_argument('--input', type=Path)
parser.add_argument('--service-stopped', action='store_true', help='Confirm all database users are stopped before restore')
args = parser.parse_args(argv)
database = args.db.resolve()
directory = (args.backup_dir or database.parent/'backups').resolve()
try:
if args.command == 'backup':
path = snapshot_database(database, unique_backup_path(directory, 'manual'))
print('Backup: ' + str(path))
elif args.command == 'daily':
print('Backup: ' + str(daily_backup(database, directory)))
elif args.command == 'list':
for path in sorted(directory.glob('*.db'), reverse=True):
print(json.dumps({'file':str(path), 'bytes':path.stat().st_size}, ensure_ascii=False))
elif args.command == 'check':
print(check_database(args.input or database))
elif args.command == 'restore':
if not args.service_stopped:
parser.error('Restore requires --service-stopped; stop the app and all database users first')
if args.input is None:
parser.error('Restore requires --input')
safety = restore_database(database, args.input, directory)
print('Restored: ' + str(database))
if safety:
print('Safety backup: ' + str(safety))
except (OSError, ValueError, RuntimeError, sqlite3.Error) as error:
print('Database operation failed: ' + str(error), file=sys.stderr)
return 1
return 0
if __name__ == '__main__':
raise SystemExit(main())