163 lines
4.1 KiB
Python
163 lines
4.1 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
# -*- coding: utf-8 -*-
|
|||
|
|
"""
|
|||
|
|
数据库迁移脚本:为 referral_bindings 表添加新字段
|
|||
|
|
用于支持新的分销逻辑(立即切换绑定、购买累加)
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
import sys
|
|||
|
|
import pymysql
|
|||
|
|
from dotenv import load_dotenv
|
|||
|
|
|
|||
|
|
# 加载环境变量
|
|||
|
|
load_dotenv()
|
|||
|
|
|
|||
|
|
# 数据库配置
|
|||
|
|
DB_CONFIG = {
|
|||
|
|
'host': os.getenv('DB_HOST', 'localhost'),
|
|||
|
|
'port': int(os.getenv('DB_PORT', 3306)),
|
|||
|
|
'user': os.getenv('DB_USER', 'root'),
|
|||
|
|
'password': os.getenv('DB_PASSWORD', ''),
|
|||
|
|
'database': os.getenv('DB_NAME', 'mycontent_db'),
|
|||
|
|
'charset': 'utf8mb4'
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def execute_sql(cursor, sql, description):
|
|||
|
|
"""执行SQL并打印结果"""
|
|||
|
|
try:
|
|||
|
|
cursor.execute(sql)
|
|||
|
|
print(f"✅ {description}")
|
|||
|
|
return True
|
|||
|
|
except pymysql.err.OperationalError as e:
|
|||
|
|
if 'Duplicate' in str(e) or 'already exists' in str(e):
|
|||
|
|
print(f"⚠️ {description} (已存在,跳过)")
|
|||
|
|
return True
|
|||
|
|
else:
|
|||
|
|
print(f"❌ {description} 失败: {e}")
|
|||
|
|
return False
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"❌ {description} 失败: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
print("=" * 60)
|
|||
|
|
print("数据库迁移:referral_bindings 表字段升级")
|
|||
|
|
print("=" * 60)
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 连接数据库
|
|||
|
|
try:
|
|||
|
|
conn = pymysql.connect(**DB_CONFIG)
|
|||
|
|
cursor = conn.cursor()
|
|||
|
|
print(f"✅ 已连接到数据库: {DB_CONFIG['database']}")
|
|||
|
|
print()
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"❌ 数据库连接失败: {e}")
|
|||
|
|
sys.exit(1)
|
|||
|
|
|
|||
|
|
# 1. 添加新字段
|
|||
|
|
print("步骤 1: 添加新字段")
|
|||
|
|
print("-" * 60)
|
|||
|
|
|
|||
|
|
execute_sql(
|
|||
|
|
cursor,
|
|||
|
|
"""ALTER TABLE referral_bindings
|
|||
|
|
ADD COLUMN last_purchase_date DATETIME NULL COMMENT '最后一次购买时间'""",
|
|||
|
|
"添加字段 last_purchase_date"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
execute_sql(
|
|||
|
|
cursor,
|
|||
|
|
"""ALTER TABLE referral_bindings
|
|||
|
|
ADD COLUMN purchase_count INT DEFAULT 0 COMMENT '购买次数'""",
|
|||
|
|
"添加字段 purchase_count"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
execute_sql(
|
|||
|
|
cursor,
|
|||
|
|
"""ALTER TABLE referral_bindings
|
|||
|
|
ADD COLUMN total_commission DECIMAL(10,2) DEFAULT 0.00 COMMENT '累计佣金'""",
|
|||
|
|
"添加字段 total_commission"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 2. 添加索引
|
|||
|
|
print("步骤 2: 添加索引")
|
|||
|
|
print("-" * 60)
|
|||
|
|
|
|||
|
|
execute_sql(
|
|||
|
|
cursor,
|
|||
|
|
"""ALTER TABLE referral_bindings
|
|||
|
|
ADD INDEX idx_referee_status (referee_id, status)""",
|
|||
|
|
"添加索引 idx_referee_status"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
execute_sql(
|
|||
|
|
cursor,
|
|||
|
|
"""ALTER TABLE referral_bindings
|
|||
|
|
ADD INDEX idx_expiry_purchase (expiry_date, purchase_count, status)""",
|
|||
|
|
"添加索引 idx_expiry_purchase"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 3. 修改 status 枚举
|
|||
|
|
print("步骤 3: 更新 status 枚举(添加 cancelled)")
|
|||
|
|
print("-" * 60)
|
|||
|
|
|
|||
|
|
execute_sql(
|
|||
|
|
cursor,
|
|||
|
|
"""ALTER TABLE referral_bindings
|
|||
|
|
MODIFY COLUMN status ENUM('active', 'converted', 'expired', 'cancelled')
|
|||
|
|
DEFAULT 'active' COMMENT '绑定状态'""",
|
|||
|
|
"更新 status 枚举类型"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 提交更改
|
|||
|
|
conn.commit()
|
|||
|
|
|
|||
|
|
# 4. 验证字段
|
|||
|
|
print("步骤 4: 验证迁移结果")
|
|||
|
|
print("-" * 60)
|
|||
|
|
|
|||
|
|
cursor.execute("SHOW COLUMNS FROM referral_bindings")
|
|||
|
|
columns = cursor.fetchall()
|
|||
|
|
|
|||
|
|
required_fields = ['last_purchase_date', 'purchase_count', 'total_commission']
|
|||
|
|
found_fields = [col[0] for col in columns]
|
|||
|
|
|
|||
|
|
for field in required_fields:
|
|||
|
|
if field in found_fields:
|
|||
|
|
print(f"✅ 字段 {field} 已存在")
|
|||
|
|
else:
|
|||
|
|
print(f"❌ 字段 {field} 未找到")
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 5. 显示索引
|
|||
|
|
print("步骤 5: 当前索引列表")
|
|||
|
|
print("-" * 60)
|
|||
|
|
|
|||
|
|
cursor.execute("SHOW INDEX FROM referral_bindings")
|
|||
|
|
indexes = cursor.fetchall()
|
|||
|
|
|
|||
|
|
for idx in indexes:
|
|||
|
|
print(f" - {idx[2]} ({idx[4]})")
|
|||
|
|
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# 关闭连接
|
|||
|
|
cursor.close()
|
|||
|
|
conn.close()
|
|||
|
|
|
|||
|
|
print("=" * 60)
|
|||
|
|
print("✅ 迁移完成!")
|
|||
|
|
print("=" * 60)
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|