Files
njts-accounting-core/backend/cleanup_script.py
2026-02-20 15:47:27 +09:00

102 lines
3.9 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Cleanup script for running inside Docker container
"""
import os
import sys
# Add current dir to path so we can import app
sys.path.insert(0, '/app')
from app.core.database import get_connection
def cleanup():
with get_connection() as conn:
with conn.cursor() as cur:
print("=" * 80)
print("【データベースクリーンアップ】")
print("=" * 80)
print()
# Step 1: Find orphan reverse entries
print("【ステップ1: 削除対象となる逆仕訳を検索】")
cur.execute("""
SELECT journal_entry_id, description, entry_date, is_latest
FROM journal_entries
WHERE is_deleted = false AND is_latest = false
AND parent_entry_id IS NULL AND original_entry_id IS NULL
ORDER BY created_at DESC
""")
rows = cur.fetchall()
print(f" 見つかったレコード: {len(rows)}")
for i, r in enumerate(rows[:5]):
print(f" {i+1}. ID={r['journal_entry_id']}: {r['description']} ({r['entry_date']})")
if len(rows) > 5:
print(f" ... 他 {len(rows)-5}")
if len(rows) > 0:
print()
print("【ステップ2: レコードを削除】")
ids = [r['journal_entry_id'] for r in rows]
# Delete journal_lines first
cur.execute("DELETE FROM journal_lines WHERE journal_entry_id = ANY(%s)", (ids,))
lines_cnt = cur.rowcount
# Delete journal_entries
cur.execute("DELETE FROM journal_entries WHERE journal_entry_id = ANY(%s)", (ids,))
entries_cnt = cur.rowcount
conn.commit()
print(f" 削除完了: {entries_cnt} 仕訳エントリ, {lines_cnt} 仕訳行")
else:
print(" 削除対象のレコードがありません")
print()
print("【ステップ3: クリーンアップ後の統計】")
cur.execute("SELECT COUNT(*) FROM journal_entries WHERE is_deleted = false")
total = cur.fetchone()
print(f" 総レコード数: {total['count']}")
cur.execute("SELECT COUNT(*) FROM journal_entries WHERE is_deleted = false AND is_latest = true")
latest = cur.fetchone()
print(f" is_latest=true: {latest['count']}")
cur.execute("SELECT COUNT(*) FROM journal_entries WHERE is_deleted = false AND is_latest = false")
old = cur.fetchone()
print(f" is_latest=false: {old['count']}")
# Check data integrity
print()
print("【データ整合性の確認】")
cur.execute("""
SELECT
COALESCE(original_entry_id, journal_entry_id) as chain_id,
COUNT(*) as total,
SUM(CASE WHEN is_latest = true THEN 1 ELSE 0 END) as latest_cnt
FROM journal_entries
WHERE is_deleted = false
GROUP BY COALESCE(original_entry_id, journal_entry_id)
HAVING COUNT(*) > 1
""")
chains = cur.fetchall()
print(f" 複数バージョンのチェーン: {len(chains)}")
if chains:
for chain in chains[:3]:
print(f" Chain {chain['chain_id']}: 合計={chain['total']}, latest={chain['latest_cnt']}")
print()
print("✓ クリーンアップ完了")
if __name__ == "__main__":
try:
cleanup()
except Exception as e:
print(f"エラー: {e}")
import traceback
traceback.print_exc()
sys.exit(1)