main
parent
5b15972069
commit
a7ab5d48c9
Binary file not shown.
@ -0,0 +1,220 @@ |
||||
import sqlite3 |
||||
import os |
||||
|
||||
def migrate_and_clean(): |
||||
"""迁移data_sets表并清理不需要的表""" |
||||
|
||||
db_path = 'data_sets.db' |
||||
|
||||
if not os.path.exists(db_path): |
||||
print(f"错误: 数据库文件 {db_path} 不存在") |
||||
return |
||||
|
||||
try: |
||||
conn = sqlite3.connect(db_path) |
||||
cursor = conn.cursor() |
||||
|
||||
print("="*60) |
||||
print("开始迁移data_sets表...") |
||||
print("="*60) |
||||
|
||||
print("\n1. 检查原表状态...") |
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='data_sets'") |
||||
if not cursor.fetchone(): |
||||
print("错误: data_sets表不存在") |
||||
return |
||||
|
||||
# 检查是否已有id列 |
||||
cursor.execute("PRAGMA table_info(data_sets)") |
||||
columns = cursor.fetchall() |
||||
column_names = [col[1] for col in columns] |
||||
|
||||
if 'id' in column_names: |
||||
print("✓ 表已有id列,跳过迁移") |
||||
# 直接进入清理步骤 |
||||
cursor.execute("SELECT COUNT(*) FROM data_sets") |
||||
total_rows = cursor.fetchone()[0] |
||||
print(f"当前表行数: {total_rows}") |
||||
else: |
||||
print(f"原表有 {len(column_names)} 个列: {', '.join(column_names)}") |
||||
|
||||
print("\n2. 备份原表...") |
||||
# 删除可能存在的旧备份 |
||||
cursor.execute("DROP TABLE IF EXISTS data_sets_backup") |
||||
# 创建新备份 |
||||
cursor.execute("CREATE TABLE data_sets_backup AS SELECT * FROM data_sets") |
||||
cursor.execute("SELECT COUNT(*) FROM data_sets_backup") |
||||
backup_rows = cursor.fetchone()[0] |
||||
print(f"✓ 已创建备份表 data_sets_backup ({backup_rows}行)") |
||||
|
||||
print("\n3. 获取原表结构...") |
||||
# 构建新表列定义 |
||||
column_defs = [] |
||||
for col_info in columns: |
||||
col_name = col_info[1] |
||||
col_type = col_info[2] |
||||
col_notnull = col_info[3] |
||||
col_default = col_info[4] |
||||
|
||||
# 构建列定义 |
||||
col_def = f"{col_name} {col_type}" |
||||
if col_notnull: |
||||
col_def += " NOT NULL" |
||||
if col_default is not None: |
||||
col_def += f" DEFAULT {col_default}" |
||||
|
||||
column_defs.append(col_def) |
||||
|
||||
print("\n4. 创建新表...") |
||||
# 创建带id的新表 |
||||
create_sql = f""" |
||||
CREATE TABLE data_sets_new ( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT, |
||||
{", ".join(column_defs)} |
||||
) |
||||
""" |
||||
cursor.execute("DROP TABLE IF EXISTS data_sets_new") |
||||
cursor.execute(create_sql) |
||||
print("✓ 已创建带id的新表 data_sets_new") |
||||
|
||||
print("\n5. 复制数据...") |
||||
# 构建INSERT语句 |
||||
original_columns = [col[1] for col in columns] |
||||
columns_str = ", ".join(original_columns) |
||||
insert_sql = f""" |
||||
INSERT INTO data_sets_new ({columns_str}) |
||||
SELECT {columns_str} FROM data_sets |
||||
""" |
||||
|
||||
cursor.execute(insert_sql) |
||||
conn.commit() |
||||
|
||||
cursor.execute("SELECT COUNT(*) FROM data_sets_new") |
||||
new_rows = cursor.fetchone()[0] |
||||
print(f"✓ 已复制 {new_rows} 行数据到新表") |
||||
|
||||
if new_rows != backup_rows: |
||||
print(f"警告: 行数不匹配! 原表:{backup_rows}, 新表:{new_rows}") |
||||
return |
||||
|
||||
print("\n6. 替换原表...") |
||||
cursor.execute("DROP TABLE data_sets") |
||||
cursor.execute("ALTER TABLE data_sets_new RENAME TO data_sets") |
||||
conn.commit() |
||||
print("✓ 已用新表替换原表") |
||||
|
||||
cursor.execute("SELECT COUNT(*) FROM data_sets") |
||||
total_rows = cursor.fetchone()[0] |
||||
print(f"✓ 迁移完成,当前表行数: {total_rows}") |
||||
|
||||
print("\n" + "="*60) |
||||
print("开始清理数据库...") |
||||
print("="*60) |
||||
|
||||
print("\n7. 删除备份表...") |
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='data_sets_backup'") |
||||
if cursor.fetchone(): |
||||
cursor.execute("DROP TABLE data_sets_backup") |
||||
print("✓ 已删除备份表 data_sets_backup") |
||||
else: |
||||
print("✓ 备份表已不存在") |
||||
|
||||
print("\n8. 清理sqlite_sequence...") |
||||
# 更新或添加data_sets的序列 |
||||
cursor.execute("SELECT MAX(id) FROM data_sets") |
||||
max_id = cursor.fetchone()[0] or 0 |
||||
|
||||
cursor.execute("SELECT seq FROM sqlite_sequence WHERE name='data_sets'") |
||||
seq_data = cursor.fetchone() |
||||
|
||||
if seq_data: |
||||
current_seq = seq_data[0] |
||||
if current_seq < max_id: |
||||
cursor.execute("UPDATE sqlite_sequence SET seq=? WHERE name='data_sets'", (max_id,)) |
||||
print(f"✓ 已更新序列值: {current_seq} -> {max_id}") |
||||
else: |
||||
print(f"✓ 序列值已最新: {current_seq}") |
||||
else: |
||||
cursor.execute("INSERT INTO sqlite_sequence (name, seq) VALUES ('data_sets', ?)", (max_id,)) |
||||
print(f"✓ 已创建序列: data_sets = {max_id}") |
||||
|
||||
print("\n9. 创建索引...") |
||||
# 删除可能存在的旧索引 |
||||
cursor.execute("SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='data_sets'") |
||||
existing_indexes = cursor.fetchall() |
||||
for (idx_name,) in existing_indexes: |
||||
cursor.execute(f"DROP INDEX IF EXISTS {idx_name}") |
||||
|
||||
# 创建新索引 |
||||
cursor.execute("CREATE INDEX idx_universe ON data_sets(universe)") |
||||
cursor.execute("CREATE INDEX idx_region ON data_sets(region)") |
||||
cursor.execute("CREATE INDEX idx_universe_region ON data_sets(universe, region)") |
||||
print("✓ 已创建索引: idx_universe, idx_region, idx_universe_region") |
||||
|
||||
print("\n10. 优化数据库...") |
||||
conn.commit() |
||||
conn.execute("VACUUM") |
||||
print("✓ 已执行VACUUM优化") |
||||
|
||||
print("\n11. 验证结果...") |
||||
# 检查表结构 |
||||
cursor.execute("PRAGMA table_info(data_sets)") |
||||
final_columns = [col[1] for col in cursor.fetchall()] |
||||
print(f"✓ 最终表结构: {', '.join(final_columns)}") |
||||
|
||||
# 测试查询 |
||||
cursor.execute(""" |
||||
SELECT COUNT(*) as total, |
||||
MIN(id) as min_id, |
||||
MAX(id) as max_id, |
||||
COUNT(DISTINCT id) as distinct_ids |
||||
FROM data_sets |
||||
""") |
||||
stats = cursor.fetchone() |
||||
print(f"✓ 数据统计: 总行数={stats[0]}, ID范围={stats[1]}-{stats[2]}, 唯一ID数={stats[3]}") |
||||
|
||||
# 测试分组查询 |
||||
cursor.execute(""" |
||||
SELECT count(id) as count_per_id |
||||
FROM data_sets |
||||
WHERE universe='TOP3000' AND region='USA' |
||||
GROUP BY id |
||||
LIMIT 3 |
||||
""") |
||||
test_results = cursor.fetchall() |
||||
if test_results: |
||||
print(f"✓ 分组查询测试成功 (示例前3个)") |
||||
|
||||
# 列出所有用户表 |
||||
cursor.execute(""" |
||||
SELECT name, type |
||||
FROM sqlite_master |
||||
WHERE type IN ('table', 'index') |
||||
AND name NOT LIKE 'sqlite_%' |
||||
ORDER BY type, name |
||||
""") |
||||
print("\n✓ 数据库对象:") |
||||
for obj_name, obj_type in cursor.fetchall(): |
||||
print(f" - {obj_name} ({obj_type})") |
||||
|
||||
conn.commit() |
||||
|
||||
print("\n" + "="*60) |
||||
print("✅ 迁移和清理完成!") |
||||
print("="*60) |
||||
print(f"数据库文件: {db_path}") |
||||
print(f"文件大小: {os.path.getsize(db_path) / 1024 / 1024:.2f} MB") |
||||
print(f"数据表: data_sets (带自增id)") |
||||
print("已清理: 备份表、优化序列、重建索引") |
||||
print("="*60) |
||||
|
||||
except Exception as e: |
||||
print(f"\n❌ 错误: {e}") |
||||
print("正在回滚...") |
||||
conn.rollback() |
||||
finally: |
||||
if conn: |
||||
conn.close() |
||||
|
||||
if __name__ == "__main__": |
||||
migrate_and_clean() |
||||
Loading…
Reference in new issue