172 lines
6.9 KiB
Python
172 lines
6.9 KiB
Python
"""
|
||
自動數據庫遷移 - 添加修正追踪欄位
|
||
在應用啟動時執行
|
||
"""
|
||
|
||
import os
|
||
from psycopg import connect
|
||
|
||
def run_auto_migration():
|
||
"""自動遷移:添加修正追踪欄位"""
|
||
|
||
try:
|
||
conn = connect(
|
||
host=os.getenv("DB_HOST"),
|
||
port=int(os.getenv("DB_PORT")),
|
||
dbname=os.getenv("DB_NAME"),
|
||
user=os.getenv("DB_USER"),
|
||
password=os.getenv("DB_PASSWORD"),
|
||
)
|
||
|
||
with conn.cursor() as cur:
|
||
print("\n" + "=" * 80)
|
||
print("【自動數據庫遷移】")
|
||
print("=" * 80)
|
||
|
||
# 1. 添加 is_latest 欄位
|
||
print("\n【步驟 1】檢查 is_latest 欄位...")
|
||
try:
|
||
cur.execute("""
|
||
SELECT COUNT(*)
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'journal_entries' AND column_name = 'is_latest'
|
||
""")
|
||
|
||
if cur.fetchone()[0] == 0:
|
||
# 欄位不存在,添加
|
||
try:
|
||
cur.execute("""
|
||
ALTER TABLE journal_entries
|
||
ADD COLUMN is_latest BOOLEAN DEFAULT true
|
||
""")
|
||
conn.commit()
|
||
print("✓ 欄位 is_latest 已添加")
|
||
except Exception as e:
|
||
conn.rollback()
|
||
print(f"⚠️ 無法添加 is_latest(可能由於權限): {e}")
|
||
else:
|
||
print("✓ 欄位 is_latest 已存在")
|
||
except Exception as e:
|
||
print(f"⚠️ 檢查 is_latest 失敗: {e}")
|
||
|
||
# 2. 添加 revision_count 欄位
|
||
print("\n【步驟 2】檢查 revision_count 欄位...")
|
||
try:
|
||
cur.execute("""
|
||
SELECT COUNT(*)
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'journal_entries' AND column_name = 'revision_count'
|
||
""")
|
||
|
||
if cur.fetchone()[0] == 0:
|
||
try:
|
||
cur.execute("""
|
||
ALTER TABLE journal_entries
|
||
ADD COLUMN revision_count INTEGER DEFAULT 1
|
||
""")
|
||
conn.commit()
|
||
print("✓ 欄位 revision_count 已添加")
|
||
except Exception as e:
|
||
conn.rollback()
|
||
print(f"⚠️ 無法添加 revision_count(可能由於權限): {e}")
|
||
else:
|
||
print("✓ 欄位 revision_count 已存在")
|
||
except Exception as e:
|
||
print(f"⚠️ 檢查 revision_count 失敗: {e}")
|
||
|
||
# 3. 添加 original_entry_id 欄位
|
||
print("\n【步驟 3】檢查 original_entry_id 欄位...")
|
||
try:
|
||
cur.execute("""
|
||
SELECT COUNT(*)
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'journal_entries' AND column_name = 'original_entry_id'
|
||
""")
|
||
|
||
if cur.fetchone()[0] == 0:
|
||
try:
|
||
cur.execute("""
|
||
ALTER TABLE journal_entries
|
||
ADD COLUMN original_entry_id INTEGER
|
||
""")
|
||
conn.commit()
|
||
print("✓ 欄位 original_entry_id 已添加")
|
||
except Exception as e:
|
||
conn.rollback()
|
||
print(f"⚠️ 無法添加 original_entry_id(可能由於權限): {e}")
|
||
else:
|
||
print("✓ 欄位 original_entry_id 已存在")
|
||
except Exception as e:
|
||
print(f"⚠️ 檢查 original_entry_id 失敗: {e}")
|
||
|
||
# 4. 創建索引
|
||
print("\n【步驟 4】創建索引...")
|
||
try:
|
||
cur.execute("""
|
||
CREATE INDEX IF NOT EXISTS idx_journal_entries_is_latest
|
||
ON journal_entries(is_latest, entry_date)
|
||
""")
|
||
conn.commit()
|
||
print("✓ 索引 idx_journal_entries_is_latest 已創建")
|
||
except Exception as e:
|
||
print(f"⚠️ 無法創建索引: {e}")
|
||
|
||
# 5. 驗證
|
||
print("\n【步驟 5】驗證新欄位...")
|
||
try:
|
||
cur.execute("""
|
||
SELECT column_name, data_type
|
||
FROM information_schema.columns
|
||
WHERE table_name = 'journal_entries'
|
||
AND column_name IN ('is_latest', 'revision_count', 'original_entry_id')
|
||
ORDER BY ordinal_position
|
||
""")
|
||
|
||
rows = cur.fetchall()
|
||
if rows:
|
||
for row in rows:
|
||
col_name = row[0]
|
||
data_type = row[1]
|
||
print(f" ✓ {col_name}: {data_type}")
|
||
else:
|
||
print(" ℹ️ 新欄位尚未存在(需要管理員執行遷移 SQL)")
|
||
except Exception as e:
|
||
print(f"⚠️ 驗證失敗: {e}")
|
||
|
||
print("\n" + "=" * 80)
|
||
print("✓ 自動遷移檢查完成!")
|
||
print("=" * 80 + "\n")
|
||
|
||
conn.close()
|
||
|
||
# ── ねんきんポータル テーブル作成 ──
|
||
try:
|
||
from app.modules.nenkin_portal.migration import create_nenkin_tables
|
||
create_nenkin_tables()
|
||
except Exception as e:
|
||
print(f"⚠️ ねんきんポータル テーブル作成エラー(無視): {e}")
|
||
|
||
# ── 銀行明細テーブル作成 ──
|
||
try:
|
||
from app.modules.bank_statements.migration import create_bank_statement_table
|
||
create_bank_statement_table()
|
||
except Exception as e:
|
||
print(f"⚠️ 銀行明細テーブル作成エラー(無視): {e}")
|
||
|
||
except Exception as e:
|
||
print(f"\n❌ 無法連接到數據庫或執行遷移: {e}")
|
||
print("\n提示:")
|
||
print("1. 確認數據庫連接信息正確(DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASSWORD)")
|
||
print("2. 如果字段仍不存在,請使用管理員帳戶執行以下 SQL 命令:")
|
||
print("""
|
||
ALTER TABLE journal_entries ADD COLUMN IF NOT EXISTS is_latest BOOLEAN DEFAULT true;
|
||
ALTER TABLE journal_entries ADD COLUMN IF NOT EXISTS revision_count INTEGER DEFAULT 1;
|
||
ALTER TABLE journal_entries ADD COLUMN IF NOT EXISTS original_entry_id INTEGER;
|
||
CREATE INDEX IF NOT EXISTS idx_journal_entries_is_latest ON journal_entries(is_latest, entry_date);
|
||
""")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
run_auto_migration()
|
||
|