feat: 初始化考培练系统项目
- 从服务器拉取完整代码 - 按框架规范整理项目结构 - 配置 Drone CI 测试环境部署 - 包含后端(FastAPI)、前端(Vue3)、管理端 技术栈: Vue3 + TypeScript + FastAPI + MySQL
This commit is contained in:
215
backend/验证备份质量.py
Executable file
215
backend/验证备份质量.py
Executable file
@@ -0,0 +1,215 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
考培练系统数据库备份质量验证脚本
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import aiomysql
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
async def verify_backup_quality():
|
||||
"""验证数据库备份质量"""
|
||||
|
||||
print("🔍 考培练系统数据库备份质量验证")
|
||||
print("=" * 50)
|
||||
|
||||
try:
|
||||
# 连接数据库
|
||||
conn = await aiomysql.connect(
|
||||
host='127.0.0.1',
|
||||
port=3306,
|
||||
user='root',
|
||||
password='root',
|
||||
db='kaopeilian',
|
||||
charset='utf8mb4'
|
||||
)
|
||||
|
||||
cursor = await conn.cursor()
|
||||
|
||||
# 1. 基础信息检查
|
||||
print("\n📊 1. 数据库基础信息")
|
||||
print("-" * 30)
|
||||
|
||||
await cursor.execute("SELECT VERSION()")
|
||||
version = (await cursor.fetchone())[0]
|
||||
print(f"MySQL版本: {version}")
|
||||
|
||||
await cursor.execute("SELECT DATABASE()")
|
||||
db_name = (await cursor.fetchone())[0]
|
||||
print(f"当前数据库: {db_name}")
|
||||
|
||||
await cursor.execute("SHOW VARIABLES LIKE 'character_set_database'")
|
||||
charset = (await cursor.fetchone())[1]
|
||||
print(f"数据库字符集: {charset}")
|
||||
|
||||
# 2. 表结构检查
|
||||
print("\n🏗️ 2. 表结构检查")
|
||||
print("-" * 30)
|
||||
|
||||
await cursor.execute("SHOW TABLES")
|
||||
tables = await cursor.fetchall()
|
||||
table_names = [t[0] for t in tables if t[0] != 'v_user_course_progress']
|
||||
|
||||
print(f"表数量: {len(table_names)}")
|
||||
|
||||
# 检查每个表的注释
|
||||
tables_with_comment = 0
|
||||
for table_name in table_names:
|
||||
await cursor.execute(f"SHOW CREATE TABLE {table_name}")
|
||||
create_sql = (await cursor.fetchone())[1]
|
||||
if 'COMMENT=' in create_sql:
|
||||
tables_with_comment += 1
|
||||
|
||||
print(f"有注释的表: {tables_with_comment}/{len(table_names)}")
|
||||
|
||||
# 3. 数据完整性检查
|
||||
print("\n📋 3. 数据完整性检查")
|
||||
print("-" * 30)
|
||||
|
||||
key_tables = [
|
||||
('users', '用户'),
|
||||
('courses', '课程'),
|
||||
('questions', '题目'),
|
||||
('teams', '团队'),
|
||||
('positions', '岗位'),
|
||||
('knowledge_points', '知识点'),
|
||||
('user_teams', '用户团队关联'),
|
||||
('position_courses', '岗位课程关联')
|
||||
]
|
||||
|
||||
total_records = 0
|
||||
for table, desc in key_tables:
|
||||
await cursor.execute(f"SELECT COUNT(*) FROM {table}")
|
||||
count = (await cursor.fetchone())[0]
|
||||
total_records += count
|
||||
status = "✅" if count > 0 else "❌"
|
||||
print(f"{status} {desc}: {count} 条")
|
||||
|
||||
print(f"总记录数: {total_records}")
|
||||
|
||||
# 4. 中文内容检查
|
||||
print("\n🈯 4. 中文内容检查")
|
||||
print("-" * 30)
|
||||
|
||||
# 检查用户中文姓名
|
||||
await cursor.execute("SELECT full_name FROM users WHERE full_name IS NOT NULL LIMIT 3")
|
||||
names = await cursor.fetchall()
|
||||
print("用户姓名示例:")
|
||||
for name in names:
|
||||
print(f" - {name[0]}")
|
||||
|
||||
# 检查课程中文名称
|
||||
await cursor.execute("SELECT name FROM courses LIMIT 3")
|
||||
courses = await cursor.fetchall()
|
||||
print("课程名称示例:")
|
||||
for course in courses:
|
||||
print(f" - {course[0]}")
|
||||
|
||||
# 5. COMMENT质量检查
|
||||
print("\n💬 5. COMMENT质量检查")
|
||||
print("-" * 30)
|
||||
|
||||
total_columns = 0
|
||||
columns_with_comment = 0
|
||||
|
||||
for table_name in table_names:
|
||||
await cursor.execute(f"SHOW FULL COLUMNS FROM {table_name}")
|
||||
columns = await cursor.fetchall()
|
||||
|
||||
for col in columns:
|
||||
total_columns += 1
|
||||
if col[8]: # 有COMMENT
|
||||
columns_with_comment += 1
|
||||
|
||||
comment_coverage = columns_with_comment / total_columns * 100
|
||||
print(f"列总数: {total_columns}")
|
||||
print(f"有注释的列: {columns_with_comment}")
|
||||
print(f"注释覆盖率: {comment_coverage:.1f}%")
|
||||
|
||||
# 6. 备份文件检查
|
||||
print("\n💾 6. 备份文件检查")
|
||||
print("-" * 30)
|
||||
|
||||
backup_files = [
|
||||
'kaopeilian_final_complete_backup_20250923_025629.sql',
|
||||
'kaopeilian_complete_backup_20250923_025548.sql',
|
||||
'kaopeilian_super_complete_backup_20250923_025622.sql'
|
||||
]
|
||||
|
||||
for backup_file in backup_files:
|
||||
if os.path.exists(backup_file):
|
||||
size = os.path.getsize(backup_file)
|
||||
print(f"✅ {backup_file}: {size/1024:.1f}KB")
|
||||
else:
|
||||
print(f"❌ {backup_file}: 不存在")
|
||||
|
||||
# 7. 质量评分
|
||||
print("\n⭐ 7. 质量评分")
|
||||
print("-" * 30)
|
||||
|
||||
scores = []
|
||||
|
||||
# 表结构完整性 (25分)
|
||||
structure_score = min(25, len(table_names) * 1.3)
|
||||
scores.append(('表结构完整性', structure_score, 25))
|
||||
|
||||
# 数据完整性 (25分)
|
||||
data_score = min(25, total_records * 0.3)
|
||||
scores.append(('数据完整性', data_score, 25))
|
||||
|
||||
# 注释质量 (25分)
|
||||
comment_score = comment_coverage * 0.25
|
||||
scores.append(('注释质量', comment_score, 25))
|
||||
|
||||
# 字符编码 (25分)
|
||||
encoding_score = 25 if charset == 'utf8mb4' else 15
|
||||
scores.append(('字符编码', encoding_score, 25))
|
||||
|
||||
total_score = sum(score for _, score, _ in scores)
|
||||
max_score = sum(max_s for _, _, max_s in scores)
|
||||
|
||||
for name, score, max_s in scores:
|
||||
percentage = score / max_s * 100
|
||||
print(f"{name}: {score:.1f}/{max_s} ({percentage:.1f}%)")
|
||||
|
||||
print(f"\n总分: {total_score:.1f}/{max_score} ({total_score/max_score*100:.1f}%)")
|
||||
|
||||
# 8. 最终评估
|
||||
print("\n🏆 8. 最终评估")
|
||||
print("-" * 30)
|
||||
|
||||
if total_score >= 90:
|
||||
grade = "优秀 ⭐⭐⭐⭐⭐"
|
||||
status = "🎉 备份质量优秀,可用于生产环境!"
|
||||
elif total_score >= 80:
|
||||
grade = "良好 ⭐⭐⭐⭐"
|
||||
status = "✅ 备份质量良好,建议使用。"
|
||||
elif total_score >= 70:
|
||||
grade = "合格 ⭐⭐⭐"
|
||||
status = "⚠️ 备份质量合格,可以使用但建议改进。"
|
||||
else:
|
||||
grade = "需改进 ⭐⭐"
|
||||
status = "❌ 备份质量需要改进。"
|
||||
|
||||
print(f"质量等级: {grade}")
|
||||
print(f"评估结果: {status}")
|
||||
|
||||
print(f"\n验证完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||||
|
||||
await cursor.close()
|
||||
conn.close()
|
||||
|
||||
return total_score >= 80
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 验证过程中出错: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = asyncio.run(verify_backup_quality())
|
||||
sys.exit(0 if result else 1)
|
||||
Reference in New Issue
Block a user