1+ #!/usr/bin/env python3
2+ """
3+ 用户表字段迁移脚本
4+ 为现有用户添加新字段:user_id, phone_number, avatar
5+ 将现有的 username 作为 user_id 的默认值
6+ """
7+
8+ import os
9+ import sys
10+ from pathlib import Path
11+
12+ # 添加项目根目录到Python路径
13+ PROJECT_ROOT = Path (__file__ ).parent
14+ sys .path .insert (0 , str (PROJECT_ROOT ))
15+
16+ from sqlalchemy import text
17+ from server .db_manager import db_manager
18+ from server .models .user_model import User
19+
20+
21+ def migrate_user_fields ():
22+ """执行用户字段迁移"""
23+ print ("开始用户字段迁移..." )
24+
25+ try :
26+ # 获取数据库会话
27+ db = db_manager .get_session ()
28+
29+ # 1. 添加新字段(如果不存在)
30+ print ("检查并添加新字段..." )
31+
32+ # 检查字段是否存在的SQL
33+ check_columns_sql = """
34+ SELECT column_name FROM information_schema.columns
35+ WHERE table_name = 'users' AND table_schema = DATABASE()
36+ """
37+
38+ try :
39+ result = db .execute (text (check_columns_sql ))
40+ existing_columns = [row [0 ] for row in result .fetchall ()]
41+ print (f"现有字段: { existing_columns } " )
42+
43+ # 添加缺失的字段
44+ if 'user_id' not in existing_columns :
45+ print ("添加 user_id 字段..." )
46+ db .execute (text ("ALTER TABLE users ADD COLUMN user_id VARCHAR(255)" ))
47+
48+ if 'phone_number' not in existing_columns :
49+ print ("添加 phone_number 字段..." )
50+ db .execute (text ("ALTER TABLE users ADD COLUMN phone_number VARCHAR(255)" ))
51+
52+ if 'avatar' not in existing_columns :
53+ print ("添加 avatar 字段..." )
54+ db .execute (text ("ALTER TABLE users ADD COLUMN avatar VARCHAR(500)" ))
55+
56+ db .commit ()
57+ print ("字段添加完成" )
58+
59+ except Exception as e :
60+ print (f"字段检查/添加失败: { e } " )
61+ # 对于SQLite,尝试直接添加字段
62+ try :
63+ db .execute (text ("ALTER TABLE users ADD COLUMN user_id TEXT" ))
64+ db .execute (text ("ALTER TABLE users ADD COLUMN phone_number TEXT" ))
65+ db .execute (text ("ALTER TABLE users ADD COLUMN avatar TEXT" ))
66+ db .commit ()
67+ print ("字段添加完成(SQLite模式)" )
68+ except Exception as sqlite_e :
69+ print (f"SQLite字段添加也失败: { sqlite_e } " )
70+ print ("字段可能已存在,继续执行..." )
71+
72+ # 2. 为现有用户设置默认 user_id
73+ print ("为现有用户设置默认 user_id..." )
74+
75+ # 查询所有没有 user_id 的用户
76+ users_without_user_id = db .execute (
77+ text ("SELECT id, username FROM users WHERE user_id IS NULL OR user_id = ''" )
78+ ).fetchall ()
79+
80+ print (f"找到 { len (users_without_user_id )} 个需要设置 user_id 的用户" )
81+
82+ for user_id , username in users_without_user_id :
83+ # 将 username 作为默认的 user_id
84+ print (f"为用户 { username } (ID: { user_id } ) 设置 user_id: { username } " )
85+ db .execute (
86+ text ("UPDATE users SET user_id = :user_id WHERE id = :id" ),
87+ {"user_id" : username , "id" : user_id }
88+ )
89+
90+ db .commit ()
91+
92+ # 3. 添加唯一索引
93+ print ("添加唯一索引..." )
94+ try :
95+ # 先检查索引是否存在
96+ try :
97+ db .execute (text ("CREATE UNIQUE INDEX idx_users_user_id ON users(user_id)" ))
98+ print ("创建 user_id 唯一索引" )
99+ except :
100+ print ("user_id 索引可能已存在" )
101+
102+ try :
103+ db .execute (text ("CREATE UNIQUE INDEX idx_users_phone_number ON users(phone_number) WHERE phone_number IS NOT NULL" ))
104+ print ("创建 phone_number 唯一索引" )
105+ except :
106+ print ("phone_number 索引可能已存在" )
107+
108+ db .commit ()
109+
110+ except Exception as e :
111+ print (f"索引创建失败: { e } " )
112+ print ("继续执行..." )
113+
114+ # 4. 验证迁移结果
115+ print ("验证迁移结果..." )
116+ total_users = db .execute (text ("SELECT COUNT(*) FROM users" )).scalar ()
117+ users_with_user_id = db .execute (text ("SELECT COUNT(*) FROM users WHERE user_id IS NOT NULL AND user_id != ''" )).scalar ()
118+
119+ print (f"总用户数: { total_users } " )
120+ print (f"已设置 user_id 的用户数: { users_with_user_id } " )
121+
122+ if total_users == users_with_user_id :
123+ print ("✅ 迁移成功完成!" )
124+ else :
125+ print ("❌ 迁移可能有问题,请检查数据库" )
126+
127+ except Exception as e :
128+ print (f"迁移过程中发生错误: { e } " )
129+ if 'db' in locals ():
130+ db .rollback ()
131+ raise
132+ finally :
133+ if 'db' in locals ():
134+ db .close ()
135+
136+
137+ if __name__ == "__main__" :
138+ migrate_user_fields ()
0 commit comments