Kamixitong/init_db_mysql.py

420 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
MySQL 数据库初始化脚本
KaMiXiTong 软件授权管理系统
使用 MySQL 数据库的完整版本,支持多用户和高性能
"""
import os
import sys
from datetime import datetime, timedelta, timezone
from werkzeug.security import generate_password_hash
# 添加项目根目录到Python路径
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
def load_env_config():
"""从.env文件加载配置"""
env_file = '.env'
if os.path.exists(env_file):
print(f"正在从 {env_file} 加载配置...")
with open(env_file, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
# 跳过注释和空行
if line and not line.startswith('#'):
# 解析键值对
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip().strip('"').strip("'")
os.environ[key] = value
print("配置加载完成")
else:
print(f"警告: 未找到 {env_file} 文件")
def init_mysql_database():
"""初始化 MySQL 数据库"""
print("=" * 50)
print("KaMiXiTong MySQL 数据库初始化开始...")
print("=" * 50)
# 从.env文件加载配置
load_env_config()
# 获取数据库URL
database_url = os.environ.get('DATABASE_URL')
if not database_url:
print("❌ 未设置DATABASE_URL环境变量")
print("💡 请在.env文件中配置DATABASE_URL")
print("示例: DATABASE_URL=mysql+pymysql://用户名:密码@主机:端口/数据库名")
return False
try:
# 设置数据库URL到环境变量
os.environ['DATABASE_URL'] = database_url
# 导入应用
from app import create_app, db
from app.models import Admin, Product, Version, License, Device, Ticket
from app.models.audit_log import AuditLog
# 创建应用实例
app = create_app()
print(f"数据库类型: MySQL")
print(f"数据库URL: {database_url}")
with app.app_context():
# 1. 删除所有表(如果存在)
print("\n1. 清理现有数据库表...")
db.drop_all()
print(" ✓ 已删除所有现有表")
# 2. 创建所有表
print("\n2. 创建数据库表结构...")
db.create_all()
print(" ✓ 已创建所有数据表")
# 显式提交事务以确保表被创建
db.session.commit()
# 2.1 验证表创建
print("\n2.1 验证表创建...")
from sqlalchemy import inspect
inspector = inspect(db.engine)
tables = inspector.get_table_names()
print(f" ✓ 成功创建 {len(tables)} 个表: {', '.join(tables)}")
if not tables:
raise Exception("表创建失败,没有找到任何表")
# 3. 插入初始数据
print("\n3. 插入初始数据...")
insert_mysql_data()
# 显式提交并关闭会话
db.session.commit()
db.session.close()
# 4. 显示数据库信息
print("\n4. MySQL 数据库初始化完成!")
show_mysql_database_info()
return True
except Exception as e:
print(f"\n❌ MySQL 数据库初始化失败: {e}")
import traceback
traceback.print_exc()
return False
def insert_mysql_data():
"""插入 MySQL 初始数据"""
from app import db
from app.models import Admin, Product, Version, License, Device, Ticket
from app.models.audit_log import AuditLog
# 1. 创建默认管理员账号
print(" 创建默认管理员账号...")
admin = Admin(
username='admin',
email='admin@kamaxitong.com',
role=1, # 超级管理员
status=1 # 正常
)
admin.set_password('admin123')
db.session.add(admin)
# 创建测试管理员账号
test_admin = Admin(
username='test_admin',
email='test@kamaxitong.com',
role=0, # 普通管理员
status=1 # 正常
)
test_admin.set_password('test123')
db.session.add(test_admin)
print(" ✓ 已创建管理员账号 (admin/admin123, test_admin/test123)")
# 2. 创建示例产品
print(" 创建示例产品...")
products = [
Product(
product_id='KMX001',
product_name='KaMiXiTong 专业版',
description='专业的软件授权管理系统,支持多种授权模式和完整的设备管理',
status=1
),
Product(
product_id='KMX002',
product_name='KaMiXiTong 企业版',
description='企业级软件授权管理解决方案,支持分布式部署和高并发访问',
status=1
)
]
for product in products:
db.session.add(product)
print(" ✓ 已创建2个示例产品")
# 3. 创建版本信息
print(" 创建版本信息...")
versions = [
Version(
product_id='KMX001',
version_num='1.0.0',
update_log='初始版本发布',
download_url='https://download.kamaxitong.com/v1.0.0/professional.exe',
min_license_version='1.0.0',
force_update=0,
download_status=1,
publish_status=1
),
Version(
product_id='KMX001',
version_num='1.1.0',
update_log='功能增强版本',
download_url='https://download.kamaxitong.com/v1.1.0/professional.exe',
min_license_version='1.0.0',
force_update=0,
download_status=1,
publish_status=1
),
Version(
product_id='KMX002',
version_num='2.0.0',
update_log='企业版初始版本',
download_url='https://download.kamaxitong.com/v2.0.0/enterprise.exe',
min_license_version='2.0.0',
force_update=0,
download_status=1,
publish_status=1
)
]
for version in versions:
db.session.add(version)
print(" ✓ 已创建3个版本信息")
# 4. 创建示例许可证
print(" 创建示例许可证...")
# 使用时区感知的 datetime 对象替换 utcnow()
current_time = datetime.now(timezone.utc)
licenses = [
# 永久许可证
License(
license_key=License.generate_license_key(),
product_id='KMX001',
type=1, # 正式版
status=1, # 已激活
valid_days=-1, # 永久
bind_machine_code='DEMO-MACHINE-CODE-001',
activate_time=current_time - timedelta(days=30),
expire_time=None, # 永久不过期
last_verify_time=current_time - timedelta(days=1),
unbind_count=0
),
# 1年试用期许可证
License(
license_key=License.generate_license_key(),
product_id='KMX001',
type=0, # 试用版
status=1, # 已激活
valid_days=365, # 1年
bind_machine_code='DEMO-MACHINE-CODE-002',
activate_time=current_time - timedelta(days=15),
expire_time=current_time + timedelta(days=350), # 还有350天过期
last_verify_time=current_time - timedelta(hours=6),
unbind_count=1
),
# 未激活许可证
License(
license_key=License.generate_license_key(),
product_id='KMX002',
type=1, # 正式版
status=0, # 未激活
valid_days=365, # 1年
bind_machine_code=None,
activate_time=None,
expire_time=None,
last_verify_time=None,
unbind_count=0
)
]
for license_obj in licenses:
db.session.add(license_obj)
print(" ✓ 已创建3个示例许可证")
# 5. 创建示例设备
print(" 创建示例设备...")
devices = [
Device(
machine_code='DEMO-MACHINE-CODE-001',
license_id=1, # 对应第一个许可证
product_id='KMX001',
software_version='1.1.0',
status=1, # 正常
activate_time=current_time - timedelta(days=30),
last_verify_time=current_time - timedelta(days=1)
),
Device(
machine_code='DEMO-MACHINE-CODE-002',
license_id=2, # 对应第二个许可证
product_id='KMX001',
software_version='1.0.0',
status=1, # 正常
activate_time=current_time - timedelta(days=15),
last_verify_time=current_time - timedelta(hours=6)
)
]
for device in devices:
db.session.add(device)
print(" ✓ 已创建2个示例设备")
# 6. 创建示例工单
print(" 创建示例工单...")
tickets = [
Ticket(
title='许可证激活失败',
product_id='KMX001',
software_version='1.0.0',
machine_code='CUSTOMER-MACHINE-001',
license_key='DEMO-LICENSE-KEY-001',
description='客户反馈无法激活许可证',
priority=2, # 高优先级
status=2, # 已解决
operator='admin',
remark='问题已解决',
create_time=current_time - timedelta(days=5),
update_time=current_time - timedelta(days=4),
resolve_time=current_time - timedelta(days=4)
),
Ticket(
title='功能咨询',
product_id='KMX002',
software_version='2.0.0',
machine_code=None,
license_key=None,
description='客户咨询批量购买事宜',
priority=1, # 中优先级
status=0, # 待处理
operator=None,
remark=None,
create_time=current_time - timedelta(days=2),
update_time=current_time - timedelta(days=2)
)
]
for ticket in tickets:
db.session.add(ticket)
print(" ✓ 已创建2个示例工单")
# 7. 创建审计日志示例数据
print(" 创建示例审计日志...")
audit_logs = [
AuditLog(
admin_id=1,
action='login',
target_type='system',
target_id=None,
details='管理员登录系统',
ip_address='127.0.0.1',
user_agent='Mozilla/5.0...',
create_time=current_time - timedelta(days=30)
),
AuditLog(
admin_id=1,
action='create',
target_type='product',
target_id=1,
details='创建产品 KaMiXiTong 专业版',
ip_address='127.0.0.1',
user_agent='Mozilla/5.0...',
create_time=current_time - timedelta(days=29)
)
]
for log in audit_logs:
db.session.add(log)
print(" ✓ 已创建2条示例审计日志")
# 提交所有更改
db.session.commit()
print(" ✓ 所有初始数据插入完成")
def show_mysql_database_info():
"""显示 MySQL 数据库信息"""
from app import db
from app.models import Admin, Product, Version, License, Device, Ticket
from app.models.audit_log import AuditLog
print("\n" + "=" * 50)
print("MySQL 数据库初始化信息统计")
print("=" * 50)
# 统计各表的记录数
tables_info = [
('管理员账号', Admin.query.count()),
('产品', Product.query.count()),
('版本', Version.query.count()),
('许可证', License.query.count()),
('设备', Device.query.count()),
('工单', Ticket.query.count()),
('审计日志', AuditLog.query.count())
]
for table_name, count in tables_info:
print(f" {table_name:8} : {count:3} 条记录")
print("\n" + "=" * 50)
print("默认登录信息")
print("=" * 50)
print(" 超级管理员: admin / admin123")
print(" 普通管理员: test_admin / test123")
print("\n注意事项:")
print(" 1. 请在生产环境中修改默认密码")
print(" 2. 确保MySQL服务正常运行")
print(" 3. 修改 .env 文件中的 DATABASE_URL 为正确的MySQL配置")
print(" 4. 定期备份数据库")
print("=" * 50)
def main():
"""主函数"""
try:
# 检查是否安装了PyMySQL
try:
import pymysql
except ImportError:
print("❌ 未安装PyMySQL请运行: pip install PyMySQL")
sys.exit(1)
# 初始化MySQL数据库
success = init_mysql_database()
if success:
print("\n🎉 MySQL 数据库初始化成功!")
print("\n启动服务器:")
print(" python run.py")
print("")
print(" python start.py")
print("\n访问: http://localhost:5000")
else:
print("\n❌ MySQL 数据库初始化失败!")
sys.exit(1)
except Exception as e:
print(f"\n❌ 初始化失败: {e}")
sys.exit(1)
if __name__ == '__main__':
main()