This commit is contained in:
admin
2026-02-20 15:47:27 +09:00
parent c60cbf2d9a
commit 584530937b
108 changed files with 12112 additions and 416 deletions

149
check_data_integrity.py Normal file
View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
検查和清理逆仕訳データと不正なis_latest標記
"""
import psycopg
from psycopg.rows import dict_row
def check_and_cleanup():
try:
conn = psycopg.connect(
host="127.0.0.1",
port=5432,
dbname="njts_accounting",
user="postgres",
password="postgres",
connect_timeout=3
)
with conn:
with conn.cursor(row_factory=dict_row) as cur:
print("=" * 80)
print("【ステップ1】逆仕訳データの検出")
print("=" * 80)
# 検査是否存在通过反向分录来处理修改的数据
cur.execute("""
SELECT
j1.journal_entry_id as original_id,
j1.description as original_desc,
j1.entry_date as original_date,
j2.journal_entry_id as reverse_id,
j2.description as reverse_desc,
j2.entry_date as reverse_date
FROM journal_entries j1
JOIN journal_lines l1 ON l1.journal_entry_id = j1.journal_entry_id
JOIN journal_entries j2 ON j1.journal_entry_id = j2.parent_entry_id
JOIN journal_lines l2 ON l2.journal_entry_id = j2.journal_entry_id
AND l2.account_id = l1.account_id
AND l2.debit = l1.credit
AND l2.credit = l1.debit
WHERE j1.is_deleted = false
AND j2.is_deleted = false
GROUP BY j1.journal_entry_id, j1.description, j1.entry_date,
j2.journal_entry_id, j2.description, j2.entry_date
LIMIT 20
""")
reverse_entries = cur.fetchall()
if reverse_entries:
print(f"見つかった逆仕訳ペア: {len(reverse_entries)}")
for entry in reverse_entries:
print(f"ID={entry['original_id']} ({entry['original_desc']}) {entry['original_date']}")
print(f"ID={entry['reverse_id']} ({entry['reverse_desc']}) {entry['reverse_date']}")
else:
print("逆仕訳ペアが見つかりません")
print()
print("=" * 80)
print("【ステップ2】is_latest=false だけど修正鎖に含まれない孤立記録")
print("=" * 80)
cur.execute("""
SELECT
journal_entry_id,
description,
is_latest,
is_deleted,
parent_entry_id,
original_entry_id,
entry_date
FROM journal_entries
WHERE is_latest = false
AND (original_entry_id IS NULL AND parent_entry_id IS NULL)
AND is_deleted = false
LIMIT 20
""")
orphan_entries = cur.fetchall()
if orphan_entries:
print(f"孤立記録が見つかりました: {len(orphan_entries)}")
for entry in orphan_entries:
print(f" ID={entry['journal_entry_id']}: {entry['description']} (date={entry['entry_date']})")
else:
print("孤立記録が見つかりません")
print()
print("=" * 80)
print("【ステップ3】修正鎖の整体性確認")
print("=" * 80)
# 检查是否有parent_entry_id指向不存在的記録
cur.execute("""
SELECT
je.journal_entry_id,
je.parent_entry_id,
je.description
FROM journal_entries je
LEFT JOIN journal_entries parent ON parent.journal_entry_id = je.parent_entry_id
WHERE je.parent_entry_id IS NOT NULL
AND parent.journal_entry_id IS NULL
LIMIT 20
""")
broken_links = cur.fetchall()
if broken_links:
print(f"破损されたリンク が見つかりました: {len(broken_links)}")
for entry in broken_links:
print(f" ID={entry['journal_entry_id']}: 削除されたparen_entry_id={entry['parent_entry_id']}")
else:
print("破损されたリンクが見つかりません")
print()
print("=" * 80)
print("【ステップ4】修正被修改的还有没有更新成正确is_latest的记录")
print("=" * 80)
# 检查是否有多个is_latest=true在同一修正鎖中
cur.execute("""
SELECT
original_entry_id,
COUNT(*) as total_count,
SUM(CASE WHEN is_latest = true THEN 1 ELSE 0 END) as latest_count,
SUM(CASE WHEN is_latest = false THEN 1 ELSE 0 END) as old_count
FROM journal_entries
WHERE original_entry_id IS NOT NULL
GROUP BY original_entry_id
HAVING SUM(CASE WHEN is_latest = true THEN 1 ELSE 0 END) != 1
""")
bad_chains = cur.fetchall()
if bad_chains:
print(f"不正合な修正鎖が見つかりました: {len(bad_chains)}")
for chain in bad_chains:
print(f" original_id={chain['original_entry_id']}: 合計={chain['total_count']}, latest={chain['latest_count']}, old={chain['old_count']}")
else:
print("正常な修正鎖のみです")
conn.close()
return True
except Exception as e:
print(f"エラー: {e}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
check_and_cleanup()