filesend/backend/migrations/add_team_leader_features.py

174 lines
5.9 KiB
Python
Raw Permalink Normal View History

2025-10-10 17:25:29 +08:00
#!/usr/bin/env python3
"""
数据库迁移脚本添加团队长功能
添加用户表字段is_team_leader
创建团队关系表team_members
"""
import sqlite3
import os
def migrate_database():
"""执行数据库迁移"""
# 数据库文件路径
db_path = os.path.join(os.path.dirname(__file__), '..', 'instance', 'filesend.db')
if not os.path.exists(db_path):
print(f"数据库文件不存在: {db_path}")
return False
try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# 1. 添加 is_team_leader 字段到 users 表
print("1. 检查并添加 is_team_leader 字段到 users 表...")
cursor.execute("PRAGMA table_info(users)")
columns = [column[1] for column in cursor.fetchall()]
if 'is_team_leader' not in columns:
cursor.execute("""
ALTER TABLE users ADD COLUMN is_team_leader BOOLEAN DEFAULT 0
""")
print(" - 成功添加 is_team_leader 字段")
else:
print(" - is_team_leader 字段已存在,跳过")
# 2. 创建 team_members 表
print("2. 创建 team_members 表...")
cursor.execute("""
CREATE TABLE IF NOT EXISTS team_members (
id INTEGER PRIMARY KEY AUTOINCREMENT,
leader_id INTEGER NOT NULL,
member_id INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (leader_id) REFERENCES users (id) ON DELETE CASCADE,
FOREIGN KEY (member_id) REFERENCES users (id) ON DELETE CASCADE,
UNIQUE (member_id)
)
""")
print(" - 成功创建 team_members 表")
# 3. 创建索引优化查询性能
print("3. 创建索引...")
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_team_members_leader_id ON team_members(leader_id)
""")
cursor.execute("""
CREATE INDEX IF NOT EXISTS idx_team_members_member_id ON team_members(member_id)
""")
print(" - 成功创建索引")
# 4. 更新现有管理员用户为团队长(可选)
print("4. 更新现有管理员用户为团队长...")
cursor.execute("""
UPDATE users SET is_team_leader = 1 WHERE is_admin = 1
""")
updated_rows = cursor.rowcount
print(f" - 更新了 {updated_rows} 个管理员用户为团队长")
# 提交事务
conn.commit()
print("\n数据库迁移完成!")
# 显示迁移结果
print("\n迁移结果:")
cursor.execute("SELECT COUNT(*) FROM users WHERE is_team_leader = 1")
team_leader_count = cursor.fetchone()[0]
print(f"- 团队长用户数量: {team_leader_count}")
cursor.execute("SELECT COUNT(*) FROM team_members")
member_count = cursor.fetchone()[0]
print(f"- 团队成员数量: {member_count}")
return True
except sqlite3.Error as e:
print(f"数据库迁移失败: {e}")
conn.rollback()
return False
finally:
conn.close()
def rollback_migration():
"""回滚迁移(谨慎使用)"""
db_path = os.path.join(os.path.dirname(__file__), '..', 'instance', 'filesend.db')
try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
print("开始回滚团队长功能迁移...")
# 删除 team_members 表
cursor.execute("DROP TABLE IF EXISTS team_members")
print("- 删除 team_members 表")
# 删除 users 表的 is_team_leader 字段
# SQLite 不支持直接删除列,需要重建表
print("- 重建 users 表(移除 is_team_leader 字段)...")
# 获取现有表结构
cursor.execute("PRAGMA table_info(users)")
columns = cursor.fetchall()
# 构建不包含 is_team_leader 的列定义
column_defs = []
for col in columns:
if col[1] != 'is_team_leader':
col_name = col[1]
col_type = col[2]
not_null = "NOT NULL" if col[3] else ""
default = f"DEFAULT {col[4]}" if col[4] is not None else ""
pk = "PRIMARY KEY" if col[5] else ""
column_defs.append(f"{col_name} {col_type} {not_null} {default} {pk}".strip())
# 创建新表
cursor.execute(f"""
CREATE TABLE users_new (
{', '.join(column_defs)}
)
""")
# 复制数据
column_names = [col[1] for col in columns if col[1] != 'is_team_leader']
cursor.execute(f"""
INSERT INTO users_new ({', '.join(column_names)})
SELECT {', '.join(column_names)} FROM users
""")
# 删除旧表,重命名新表
cursor.execute("DROP TABLE users")
cursor.execute("ALTER TABLE users_new RENAME TO users")
print("- 成功重建 users 表")
conn.commit()
print("回滚完成!")
except sqlite3.Error as e:
print(f"回滚失败: {e}")
conn.rollback()
finally:
conn.close()
if __name__ == "__main__":
import sys
if len(sys.argv) > 1 and sys.argv[1] == "rollback":
confirm = input("确定要回滚团队长功能迁移吗?这将删除所有团队数据!(yes/no): ")
if confirm.lower() == 'yes':
rollback_migration()
else:
print("取消回滚操作")
else:
print("开始执行团队长功能数据库迁移...")
print("=" * 50)
success = migrate_database()
if success:
print("\n✅ 迁移成功完成!")
else:
print("\n❌ 迁移失败!")
sys.exit(1)