修正
This commit is contained in:
146
backend/run_db_migration.py
Normal file
146
backend/run_db_migration.py
Normal file
@@ -0,0 +1,146 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
数据库迁移脚本:添加 revision_count, is_latest, original_entry_id 字段
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# 加载 .env 文件
|
||||
env_file = Path(__file__).parent.parent / ".env"
|
||||
if env_file.exists():
|
||||
with open(env_file) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if line and not line.startswith("#"):
|
||||
key, value = line.split("=", 1)
|
||||
os.environ[key.strip()] = value.strip()
|
||||
|
||||
from psycopg import connect
|
||||
|
||||
def run_migration():
|
||||
try:
|
||||
# 从环境变量获取数据库连接信息
|
||||
db_password = os.getenv("DB_PASSWORD")
|
||||
print(f"📛 连接数据库: {os.getenv('DB_HOST')}:{os.getenv('DB_PORT')}/{os.getenv('DB_NAME')}")
|
||||
print(f"👤 用户: {os.getenv('DB_USER')}")
|
||||
|
||||
conn = connect(
|
||||
host=os.getenv("DB_HOST"),
|
||||
port=int(os.getenv("DB_PORT")),
|
||||
dbname=os.getenv("DB_NAME"),
|
||||
user=os.getenv("DB_USER"),
|
||||
password=db_password if db_password else None,
|
||||
)
|
||||
|
||||
with conn.cursor() as cur:
|
||||
# 首先检查字段是否存在
|
||||
print("🔄 检查字段是否存在...")
|
||||
cur.execute("""
|
||||
SELECT column_name FROM information_schema.columns
|
||||
WHERE table_name = 'journal_entries'
|
||||
AND column_name IN ('is_latest', 'revision_count', 'original_entry_id')
|
||||
""")
|
||||
existing_columns = {row[0] for row in cur.fetchall()}
|
||||
print(f"✓ 已存在的字段: {existing_columns if existing_columns else '无'}")
|
||||
|
||||
# 添加 is_latest 字段
|
||||
if 'is_latest' not in existing_columns:
|
||||
print("🔄 添加 is_latest 字段...")
|
||||
try:
|
||||
cur.execute("""
|
||||
ALTER TABLE journal_entries
|
||||
ADD COLUMN is_latest BOOLEAN DEFAULT true;
|
||||
""")
|
||||
conn.commit()
|
||||
print("✓ is_latest 字段已添加")
|
||||
except Exception as e:
|
||||
print(f"✗ 添加失败: {e}")
|
||||
conn.rollback()
|
||||
else:
|
||||
print("✓ is_latest 字段已存在")
|
||||
|
||||
# 添加 revision_count 字段
|
||||
if 'revision_count' not in existing_columns:
|
||||
print("🔄 添加 revision_count 字段...")
|
||||
try:
|
||||
cur.execute("""
|
||||
ALTER TABLE journal_entries
|
||||
ADD COLUMN revision_count INTEGER DEFAULT 1;
|
||||
""")
|
||||
conn.commit()
|
||||
print("✓ revision_count 字段已添加")
|
||||
except Exception as e:
|
||||
print(f"✗ 添加失败: {e}")
|
||||
conn.rollback()
|
||||
else:
|
||||
print("✓ revision_count 字段已存在")
|
||||
|
||||
# 添加 original_entry_id 字段
|
||||
if 'original_entry_id' not in existing_columns:
|
||||
print("🔄 添加 original_entry_id 字段...")
|
||||
try:
|
||||
cur.execute("""
|
||||
ALTER TABLE journal_entries
|
||||
ADD COLUMN original_entry_id INTEGER;
|
||||
""")
|
||||
conn.commit()
|
||||
print("✓ original_entry_id 字段已添加")
|
||||
except Exception as e:
|
||||
print(f"✗ 添加失败: {e}")
|
||||
conn.rollback()
|
||||
else:
|
||||
print("✓ original_entry_id 字段已存在")
|
||||
|
||||
# 创建索引
|
||||
print("🔄 创建索引...")
|
||||
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}")
|
||||
conn.rollback()
|
||||
|
||||
try:
|
||||
cur.execute("""
|
||||
CREATE INDEX IF NOT EXISTS idx_journal_entries_original_entry_id
|
||||
ON journal_entries(original_entry_id);
|
||||
""")
|
||||
conn.commit()
|
||||
print("✓ idx_journal_entries_original_entry_id 索引已创建")
|
||||
except Exception as e:
|
||||
print(f"✗ 创建索引失败: {e}")
|
||||
conn.rollback()
|
||||
|
||||
# 验证字段
|
||||
print("🔄 验证字段...")
|
||||
cur.execute("""
|
||||
SELECT column_name, data_type, is_nullable
|
||||
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()
|
||||
print("\n📋 数据库字段信息:")
|
||||
for row in rows:
|
||||
print(f" - {row[0]}: {row[1]} (nullable: {row[2]})")
|
||||
|
||||
conn.close()
|
||||
|
||||
print("\n✅ 迁移完成!")
|
||||
return 0
|
||||
|
||||
except Exception as e:
|
||||
print(f"\n❌ 迁移失败: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run_migration())
|
||||
Reference in New Issue
Block a user