mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-24 05:26:58 +00:00
重构代码生成模块,删除冗余文件并优化结构: 1. 删除旧的form、page、table等相关文件 2. 新增gencode模块基础结构 3. 移动jinja2工具类和模板引擎初始化器到utils目录 4. 优化数据库模型关系定义 5. 更新nginx配置支持WebSocket 6. 添加正则验证和加密工具类 7. 修复菜单和部门模型的循环引用问题 8. 优化初始化脚本和配置加载逻辑 调整初始化流程,使用统一会话管理: 1. 修改数据库初始化使用AsyncSessionLocal 2. 优化定时任务初始化逻辑 3. 统一配置和字典服务初始化方式 4. 修复模型关系定义导致的循环导入问题 其他改进: 1. 更新requirements.txt添加依赖 2. 调整IP白名单配置 3. 优化数据库连接日志输出 4. 修复模型继承关系问题
105 lines
3.7 KiB
Python
105 lines
3.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import uuid
|
|
import json
|
|
from pathlib import Path
|
|
from typing import Dict, List
|
|
from sqlalchemy import select, func
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.core.logger import logger
|
|
from app.config.setting import settings
|
|
|
|
from app.api.v1.module_system.user.model import UserModel, UserRolesModel, UserPositionsModel
|
|
from app.api.v1.module_system.role.model import RoleModel, RoleDeptsModel, RoleMenusModel
|
|
from app.api.v1.module_system.position.model import PositionModel
|
|
from app.api.v1.module_system.dept.model import DeptModel
|
|
from app.api.v1.module_system.menu.model import MenuModel
|
|
from app.api.v1.module_system.config.model import ConfigModel
|
|
from app.api.v1.module_system.dict.model import DictTypeModel, DictDataModel
|
|
from app.core.database import AsyncSessionLocal
|
|
|
|
|
|
class InitializeData:
|
|
"""
|
|
初始化数据库和基础数据
|
|
"""
|
|
|
|
def __init__(self) -> None:
|
|
# 按照依赖关系排序:先创建基础表,再创建关联表
|
|
self.prepare_init_models = [
|
|
# 部门表(自引用,需要先创建)
|
|
DeptModel,
|
|
# 菜单表(自引用,需要先创建)
|
|
MenuModel,
|
|
# 用户表(依赖部门和角色)
|
|
UserModel,
|
|
# 角色表(依赖菜单和部门)
|
|
RoleModel,
|
|
# 岗位表(无外键依赖)
|
|
PositionModel,
|
|
# 基础表(无外键依赖)
|
|
ConfigModel,
|
|
DictTypeModel,
|
|
DictDataModel,
|
|
# 关联表(依赖基础表)
|
|
UserPositionsModel,
|
|
UserRolesModel,
|
|
RoleDeptsModel,
|
|
RoleMenusModel,
|
|
]
|
|
|
|
async def __init_data(self, db: AsyncSession) -> None:
|
|
"""初始化基础数据"""
|
|
for model in self.prepare_init_models:
|
|
table_name = model.__tablename__
|
|
|
|
# 检查表中是否已经有数据
|
|
count_result = await db.execute(select(func.count()).select_from(model))
|
|
existing_count = count_result.scalar()
|
|
|
|
if existing_count > 0:
|
|
logger.warning(f"跳过 {table_name} 表数据初始化(表已存在 {existing_count} 条记录)")
|
|
continue
|
|
|
|
data = await self.__get_data(table_name)
|
|
if not data:
|
|
logger.warning(f"跳过 {table_name} 表,无初始化数据")
|
|
continue
|
|
|
|
try:
|
|
# 表为空,直接插入全部数据
|
|
objs = [model(**item) for item in data]
|
|
db.add_all(objs)
|
|
await db.flush()
|
|
logger.info(f"已向 {table_name} 表写入 {len(objs)} 条记录")
|
|
|
|
except Exception as e:
|
|
logger.error(f"初始化 {table_name} 表数据失败: {str(e)}")
|
|
raise
|
|
|
|
async 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 init_db(self) -> None:
|
|
"""
|
|
执行完整初始化流程
|
|
"""
|
|
# 使用单个会话完成所有初始化操作
|
|
async with AsyncSessionLocal() as session:
|
|
# async with session.begin():
|
|
await self.__init_data(session)
|
|
|