mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-20 20:39:55 +00:00
本次提交主要包含以下变更: 1. 新增任务管理模块,支持定时任务的创建、更新、删除和状态管理 2. 新增字典管理模块,用于维护系统中常用的固定数据 3. 优化系统配置,移除Celery,改用APScheduler进行任务调度 4. 修复部分前端组件的样式问题,统一输入框宽度 5. 更新文档和相关图片资源,完善系统功能描述 这些变更旨在增强系统的可维护性和功能性,提供更灵活的任务调度机制和更便捷的字典数据管理方式。
115 lines
3.9 KiB
Python
115 lines
3.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Dict, List
|
|
|
|
from app.core.logger import logger
|
|
from app.config.setting import settings
|
|
from app.core.base_model import ModelBase
|
|
from app.core.database import async_engine, async_session
|
|
from app.api.v1.models.system import (
|
|
user_model,
|
|
dept_model,
|
|
role_model,
|
|
menu_model,
|
|
position_model,
|
|
operation_log_model,
|
|
notice_model,
|
|
config_model,
|
|
dict_model,
|
|
job_model
|
|
)
|
|
|
|
class InitializeData:
|
|
"""
|
|
初始化数据库和基础数据
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
self.engine = async_engine
|
|
self.session = async_session()
|
|
self.prepare_init_models = [
|
|
dept_model.DeptModel,
|
|
menu_model.MenuModel,
|
|
user_model.UserModel,
|
|
position_model.PositionModel,
|
|
user_model.UserPositionsModel,
|
|
role_model.RoleModel,
|
|
user_model.UserRolesModel,
|
|
role_model.RoleDeptsModel,
|
|
role_model.RoleMenusModel,
|
|
notice_model.NoticeModel,
|
|
config_model.ConfigModel,
|
|
operation_log_model.OperationLogModel,
|
|
dict_model.DictTypeModel,
|
|
dict_model.DictDataModel,
|
|
job_model.JobModel,
|
|
]
|
|
|
|
async def __init_model(self) -> None:
|
|
"""初始化数据库表结构"""
|
|
try:
|
|
async with self.engine.begin() as conn:
|
|
# 使用事务确保原子性
|
|
await conn.run_sync(ModelBase.metadata.drop_all)
|
|
logger.info("已清空所有表结构")
|
|
await conn.run_sync(ModelBase.metadata.create_all)
|
|
logger.info("已重新创建所有表结构")
|
|
except Exception as e:
|
|
logger.error(f"初始化数据库表结构失败: {str(e)}")
|
|
raise
|
|
|
|
async def __init_data(self) -> None:
|
|
"""初始化基础数据"""
|
|
try:
|
|
async with self.session as session:
|
|
logger.info("开始初始化基础数据...")
|
|
# for model in ModelBase.__subclasses__():
|
|
for model in self.prepare_init_models:
|
|
table_name = model.__tablename__
|
|
data = self.__get_data(table_name)
|
|
if not data:
|
|
logger.info(f"跳过 {table_name} 表,无初始化数据")
|
|
continue
|
|
|
|
try:
|
|
async with session.begin():
|
|
objs = [model(**item) for item in data]
|
|
session.add_all(objs)
|
|
await session.flush() # 立即刷新以检查约束
|
|
logger.info(f"已向 {table_name} 表写入 {len(objs)} 条记录")
|
|
except Exception as e:
|
|
logger.error(f"初始化 {table_name} 表数据失败: {str(e)}")
|
|
raise
|
|
|
|
logger.info("基础数据初始化完成")
|
|
except Exception as e:
|
|
logger.error(f"初始化基础数据失败: {str(e)}")
|
|
raise
|
|
|
|
def __get_data(self, filename: str) -> List[Dict]:
|
|
"""读取初始化数据文件"""
|
|
json_path = Path.joinpath(settings.SCRIPT_DIR, f'{filename}.json')
|
|
if not json_path.exists():
|
|
return []
|
|
|
|
try:
|
|
with open(json_path, 'r', encoding='utf-8') as f:
|
|
return json.loads(f.read())
|
|
except json.JSONDecodeError as e:
|
|
logger.error(f"解析 {json_path} 失败: {str(e)}")
|
|
raise
|
|
except Exception as e:
|
|
logger.error(f"读取 {json_path} 失败: {str(e)}")
|
|
raise
|
|
|
|
async def run(self) -> None:
|
|
"""
|
|
执行完整初始化流程
|
|
"""
|
|
logger.info("开始执行数据库初始化...")
|
|
await self.__init_model()
|
|
await self.__init_data()
|
|
logger.info("数据库初始化完成")
|