CryptoAiAdmin项目数据库表自动创建和初始化

1. 概述

本系统采用了基于 SQLAlchemy 2.0 的异步数据库架构,实现了自动化的数据库表创建和基础数据初始化。整个初始化过程由 InitializeData 类(位于 app/scripts/initialize.py)统一管理,遵循"先创建表结构,再初始化数据"的原则,确保数据完整性和依赖关系正确性。

2. 数据库连接配置

2.1 连接管理

系统使用 app/core/database.py 中的函数创建数据库连接:

  • create_engine_and_session(): 创建同步数据库引擎和会话工厂
  • create_async_engine_and_session(): 创建异步数据库引擎和会话工厂

这些函数从配置文件中读取数据库连接参数,支持多种数据库类型(SQLite、MySQL、PostgreSQL)。

2.2 核心配置参数

  • 数据库连接URL: settings.DB_URI(同步)和 settings.ASYNC_DB_URI(异步)
  • 连接池配置: 包括连接池大小、回收时间、预检查等
  • 日志配置: 控制是否输出SQL语句

3. 模型定义架构

3.1 基础模型设计

系统采用了Mixin模式实现模型的复用和扩展:

python 复制代码
class MappedBase(AsyncAttrs, DeclarativeBase):
    __abstract__: bool = True

class ModelMixin(MappedBase):
    __abstract__: bool = True
    # 提供通用字段:id、uuid、status、description、created_time、updated_time

class UserMixin(MappedBase):
    __abstract__: bool = True
    # 提供用户审计字段:created_id、updated_id

3.2 业务模型定义

业务模型通过继承基础模型实现,例如用户模型:

python 复制代码
class UserModel(ModelMixin, UserMixin):
    __tablename__: str = "sys_user"
    __table_args__: dict[str, str] = ({'comment': '用户表'})
    
    username: Mapped[str] = mapped_column(String(32), nullable=False, unique=True, comment="用户名/登录账号")
    password: Mapped[str] = mapped_column(String(255), nullable=False, comment="密码哈希")
    # 其他字段...
    
    # 关联关系
    dept: Mapped["DeptModel | None"] = relationship(back_populates="users", lazy="selectin")
    roles: Mapped[list["RoleModel"]] = relationship(secondary="sys_user_roles", back_populates="users", lazy="selectin")

4. 表创建过程

4.1 模型加载与依赖排序

InitializeData 类中,模型按照依赖关系排序:

python 复制代码
self.prepare_init_models = [
    MenuModel,
    ParamsModel,
    DeptModel,
    RoleModel,
    DictTypeModel,
    DictDataModel,
    PositionModel,
    UserModel,
    UserRolesModel,
]

4.2 表创建实现

表创建通过 SQLAlchemy 的 metadata.create_all() 方法实现:

python 复制代码
async def __init_create_table(self) -> None:
    try:
        async with async_engine.begin() as conn:
            await conn.run_sync(MappedBase.metadata.create_all)
        log.info("✅️ 数据库表结构初始化完成")
    except Exception as e:
        log.error(f"❌️ 数据库表结构初始化失败: {str(e)}")
        raise

这个方法会自动创建所有继承自 MappedBase 的模型对应的数据库表,并处理表之间的外键关系。

5. 数据初始化过程

5.1 初始化数据存储

基础数据存储在 app/scripts/data/ 目录下的 JSON 文件中,每个文件对应一个表:

kotlin 复制代码
data/
├── sys_dept.json
├── sys_dict_data.json
├── sys_dict_type.json
├── sys_menu.json
├── sys_param.json
├── sys_role.json
├── sys_user.json
└── sys_user_roles.json

5.2 数据加载与插入

数据初始化过程包括以下步骤:

  1. 检查表是否已有数据:避免重复初始化
  2. 读取初始化数据文件:从 JSON 文件中加载数据
  3. 特殊数据处理
    • 嵌套数据处理(如部门和菜单的树形结构)
    • 关联数据处理(如字典数据与字典类型的关联)
  4. 批量插入数据 :使用 db.add_all()db.flush() 批量插入

5.3 特殊数据处理实现

5.3.1 嵌套数据处理

对于具有树形结构的数据(如部门和菜单),系统使用递归函数创建对象:

python 复制代码
def __create_objects_with_children(self, data: list[dict], model_class) -> list:
    objs = []
    
    def create_object(obj_data: dict):
        children_data = obj_data.pop('children', [])
        obj = model_class(**obj_data)
        if children_data:
            obj.children = [create_object(child) for child in children_data]
        return obj
    
    for item in data:
        objs.append(create_object(item))
    
    return objs

5.3.2 关联数据处理

对于存在关联关系的数据(如用户与角色),系统先初始化主表数据,再初始化关联表数据:

python 复制代码
# 处理字典类型表,保存类型映射
elif table_name == "sys_dict_type":
    objs = []
    for item in data:
        obj = model(**item)
        objs.append(obj)
        dict_type_mapping[item['dict_type']] = obj
# 处理字典数据表,添加dict_type_id关联
elif table_name == "sys_dict_data":
    objs = []
    for item in data:
        dict_type = item.get('dict_type')
        if dict_type in dict_type_mapping:
            item['dict_type_id'] = dict_type_mapping[dict_type].id
        else:
            log.warning(f"⚠️  未找到字典类型 {dict_type},跳过该字典数据")
            continue
        objs.append(model(**item))

6. 完整初始化流程

数据库初始化的完整流程由 init_db() 方法统一协调:

python 复制代码
async def init_db(self) -> None:
    # 先创建表结构
    await self.__init_create_table()
    
    # 再初始化数据
    async with async_db_session() as session:
        async with session.begin():
            await self.__init_data(session)
            await session.commit()

8. 总结

本系统的数据库初始化过程是一个高度自动化、可扩展的架构,通过 SQLAlchemy 2.0 的异步特性实现了高效的数据库操作。整个过程遵循了"先创建表结构,再初始化数据"的原则,确保了数据的完整性和依赖关系的正确性。同时,系统采用了Mixin模式实现模型的复用和扩展,提高了代码的可维护性。

相关推荐
wj3055853782 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
星寂樱易李2 小时前
iperf3 + Python-- 网络带宽、网速、网络稳定性
开发语言·网络·python
qingfeng154152 小时前
企业微信机器人开发:如何实现自动化与智能运营?
人工智能·python·机器人·自动化·企业微信
candyTong3 小时前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构
GetcharZp4 小时前
GitHub 2.4 万 Star!D2 正在重新定义程序员画图方式
后端
彦为君5 小时前
Agent 安全:从权限提示到沙箱隔离
python·ai·ai编程
zhangxingchao6 小时前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端
IT_陈寒6 小时前
SpringBoot那个自动配置的坑,害我排查到凌晨三点
前端·人工智能·后端
ServBay6 小时前
OpenCode 和它的7款必备插件
后端·github·ai编程