修正
This commit is contained in:
101
backend/cleanup_script.py
Normal file
101
backend/cleanup_script.py
Normal file
@@ -0,0 +1,101 @@
|
||||
#!/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)
|
||||
Reference in New Issue
Block a user