修正
This commit is contained in:
172
fix_revision_links.py
Normal file
172
fix_revision_links.py
Normal file
@@ -0,0 +1,172 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
修复数据库中的版本链接错误和is_latest标记
|
||||
"""
|
||||
import psycopg
|
||||
from datetime import datetime
|
||||
|
||||
try:
|
||||
conn = psycopg.connect(
|
||||
host='192.168.0.61',
|
||||
port=55432,
|
||||
dbname='njts_acct',
|
||||
user='njts_app',
|
||||
password='njts_app2025'
|
||||
)
|
||||
|
||||
with conn.cursor() as cur:
|
||||
print("=" * 70)
|
||||
print("【数据库修复:版本链接和is_latest标记】")
|
||||
print("=" * 70)
|
||||
|
||||
# 第一步:识别【修正後】記錄,並確保其 original_entry_id 指向真正的原始版本
|
||||
print("\n【步驟 1】修復 original_entry_id 鏈接...")
|
||||
|
||||
# 查找所有【修正後】的記錄
|
||||
cur.execute("""
|
||||
SELECT journal_entry_id, description, original_entry_id
|
||||
FROM journal_entries
|
||||
WHERE description LIKE '%【修正後】%'
|
||||
AND is_deleted = false
|
||||
ORDER BY journal_entry_id
|
||||
""")
|
||||
|
||||
corrupted_count = 0
|
||||
for row in cur.fetchall():
|
||||
je_id, desc, orig_id = row
|
||||
|
||||
# 如果original_entry_id指向另一个【修正後】記錄,就往上追溯
|
||||
if orig_id:
|
||||
cur.execute("""
|
||||
SELECT original_entry_id, description
|
||||
FROM journal_entries
|
||||
WHERE journal_entry_id = %s
|
||||
""", (orig_id,))
|
||||
parent_row = cur.fetchone()
|
||||
|
||||
if parent_row:
|
||||
parent_orig_id, parent_desc = parent_row
|
||||
# 如果指向的記錄也是【修正後】,說明有鏈接錯誤
|
||||
if '【修正後】' in parent_desc and parent_orig_id and parent_orig_id != orig_id:
|
||||
print(f"\n修復 ID={je_id}: {desc[:30]}")
|
||||
print(f" 舊的 original_entry_id: {orig_id} (也是【修正後】記錄)")
|
||||
print(f" 新的 original_entry_id: {parent_orig_id}")
|
||||
|
||||
cur.execute("""
|
||||
UPDATE journal_entries
|
||||
SET original_entry_id = %s
|
||||
WHERE journal_entry_id = %s
|
||||
""", (parent_orig_id, je_id))
|
||||
corrupted_count += 1
|
||||
|
||||
conn.commit()
|
||||
if corrupted_count > 0:
|
||||
print(f"\n✓ 已修復 {corrupted_count} 條記錄的 original_entry_id")
|
||||
else:
|
||||
print("✓ 沒有發現 original_entry_id 鏈接錯誤")
|
||||
|
||||
# 第二步:重新設置 is_latest 標記
|
||||
print("\n【步驟 2】重新設置 is_latest 標記...")
|
||||
|
||||
# 清空所有 is_latest 標記
|
||||
cur.execute("UPDATE journal_entries SET is_latest = false WHERE is_deleted = false")
|
||||
conn.commit()
|
||||
|
||||
# 對每條版本鏈,只有最新版本的 is_latest = true
|
||||
cur.execute("""
|
||||
SELECT DISTINCT original_entry_id FROM journal_entries
|
||||
WHERE original_entry_id IS NOT NULL AND is_deleted = false
|
||||
UNION
|
||||
SELECT DISTINCT journal_entry_id FROM journal_entries
|
||||
WHERE original_entry_id IS NULL AND is_deleted = false
|
||||
AND journal_entry_id NOT IN (
|
||||
SELECT original_entry_id FROM journal_entries WHERE original_entry_id IS NOT NULL
|
||||
)
|
||||
""")
|
||||
|
||||
chain_heads = [row[0] for row in cur.fetchall()]
|
||||
|
||||
updated_count = 0
|
||||
for chain_head in chain_heads:
|
||||
# 找出這條鏈中最新的版本(根據 created_at 或 journal_entry_id)
|
||||
cur.execute("""
|
||||
SELECT journal_entry_id FROM journal_entries
|
||||
WHERE (journal_entry_id = %s OR original_entry_id = %s)
|
||||
AND is_deleted = false
|
||||
ORDER BY journal_entry_id DESC
|
||||
LIMIT 1
|
||||
""", (chain_head, chain_head))
|
||||
|
||||
latest = cur.fetchone()
|
||||
if latest:
|
||||
latest_id = latest[0]
|
||||
cur.execute("""
|
||||
UPDATE journal_entries
|
||||
SET is_latest = true
|
||||
WHERE journal_entry_id = %s
|
||||
""", (latest_id,))
|
||||
updated_count += 1
|
||||
|
||||
conn.commit()
|
||||
print(f"✓ 已設置 {updated_count} 條最新版本的 is_latest = true")
|
||||
|
||||
# 第三步:驗證
|
||||
print("\n【步驟 3】驗證修復結果...")
|
||||
print("-" * 70)
|
||||
|
||||
# 檢查是否有多個 is_latest=true 在同一個鏈中
|
||||
cur.execute("""
|
||||
SELECT original_entry_id, COUNT(*) as cnt
|
||||
FROM journal_entries
|
||||
WHERE is_latest = true AND is_deleted = false AND original_entry_id IS NOT NULL
|
||||
GROUP BY original_entry_id
|
||||
HAVING COUNT(*) > 1
|
||||
""")
|
||||
|
||||
duplicates = cur.fetchall()
|
||||
if duplicates:
|
||||
print("⚠️ 警告:發現重複的 is_latest=true")
|
||||
for dup in duplicates:
|
||||
print(f" original_entry_id={dup[0]}: {dup[1]} 條記錄")
|
||||
else:
|
||||
print("✓ 沒有發現重複的 is_latest=true")
|
||||
|
||||
# 統計各狀態的記錄數
|
||||
cur.execute("""
|
||||
SELECT is_latest, COUNT(*) as cnt
|
||||
FROM journal_entries
|
||||
WHERE is_deleted = false
|
||||
GROUP BY is_latest
|
||||
""")
|
||||
|
||||
stats = cur.fetchall()
|
||||
print("\n記錄統計:")
|
||||
for stat in stats:
|
||||
print(f" is_latest={stat[0]}: {stat[1]} 條")
|
||||
|
||||
# 驗證【test元】的鏈
|
||||
print("\n【test 元】鏈的驗證:")
|
||||
print("-" * 70)
|
||||
cur.execute("""
|
||||
SELECT journal_entry_id, description, is_latest, revision_count, original_entry_id
|
||||
FROM journal_entries
|
||||
WHERE (description LIKE '%test%' AND is_deleted = false)
|
||||
AND journal_entry_id >= 410
|
||||
ORDER BY journal_entry_id
|
||||
""")
|
||||
|
||||
test_records = cur.fetchall()
|
||||
for rec in test_records:
|
||||
je_id, desc, is_latest, rev_cnt, orig_id = rec
|
||||
status = "✓" if is_latest else " "
|
||||
print(f"{status} ID={je_id:3d} rev={rev_cnt} orig_id={str(orig_id):>6s} {desc[:40]}")
|
||||
|
||||
conn.close()
|
||||
print("\n" + "=" * 70)
|
||||
print("修復完成!")
|
||||
print("=" * 70)
|
||||
|
||||
except Exception as e:
|
||||
print(f'錯誤: {e}')
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
Reference in New Issue
Block a user