feat: 初始化数据库

This commit is contained in:
李如威 2025-08-22 11:15:52 +08:00
parent d076d249c0
commit ad05f55a04
11 changed files with 113 additions and 19 deletions

View File

@ -1,11 +1,16 @@
{ {
"is_init": true, "is_init": true,
"db_type": "sqlite_3", "db_type": "sqlite",
"mysql": { "mysql": {
"host": "", "host": "",
"port": "", "port": "",
"user": "", "user": "",
"password": "", "password": "",
"db_name": "" "db_name": ""
} },
"db_host": "string",
"db_port": "string",
"db_user": "string",
"db_password": "string",
"db_name": "your_workflow"
} }

View File

24
backend/app/core/db.py Normal file
View File

@ -0,0 +1,24 @@
from tortoise.contrib.fastapi import Tortoise
async def init_tortoise(db_type: str, db_config: dict):
if db_type == "mysql":
db_url = (
f"mysql://{db_config['db_user']}:{db_config['db_password']}"
f"@{db_config['db_host']}:{db_config['db_port']}/{db_config['db_name']}"
)
elif db_type == "sqlite":
db_url = f"sqlite://{db_config['db_name']}"
else:
raise ValueError("Unsupported db_type")
try:
await Tortoise.init(
db_url=db_url,
modules={"models": ["models.db"]}, # 这里写你模型所在路径
)
await Tortoise.generate_schemas()
return True
except Exception as e:
raise e
async def close_tortoise():
await Tortoise.close_connections()

View File

@ -1,10 +1,28 @@
import uvicorn import uvicorn
import os
import json
from fastapi import FastAPI from fastapi import FastAPI
from pathlib import Path
from models.schemas.system import InitStatusResponse, InitConfigRequest from models.schemas.system import InitStatusResponse, InitConfigRequest
from core.config import load_init_config, save_init_config from core.config import load_init_config, save_init_config
from core.db import init_tortoise, close_tortoise
from contextlib import asynccontextmanager
import logging
async def is_init():
init_config = await load_init_config()
init_status = init_config.get("is_init")
return init_status
@asynccontextmanager
async def lifespan(app: FastAPI):
if await is_init():
app.logger.info("初始化数据库")
await init_tortoise()
yield
app.logger.info("关闭数据库")
await close_tortoise()
def create_app(): def create_app():
@ -21,9 +39,7 @@ def create_app():
response_model=InitStatusResponse, response_model=InitStatusResponse,
) )
async def check_init(): async def check_init():
init_config = await load_init_config() return InitStatusResponse(data=await is_init())
is_init = init_config.get("is_init")
return InitStatusResponse(data=is_init)
@app.post( @app.post(
"/init_system", "/init_system",
@ -32,20 +48,35 @@ def create_app():
response_model=InitStatusResponse, response_model=InitStatusResponse,
) )
async def init_system(request: InitConfigRequest): async def init_system(request: InitConfigRequest):
app.logger.info("init_system")
try:
init_config = await load_init_config() init_config = await load_init_config()
if init_config.get('is_init'): if init_config.get('is_init'):
return InitStatusResponse(data=True) return InitStatusResponse(data=True)
# 保存配置
init_config["db_type"] = request.db_type init_config["db_type"] = request.db_type
if request.db_type == "mysql": init_config["db_host"] = request.db_host
pass init_config["db_port"] = request.db_port
init_config["db_user"] = request.db_user
init_config["db_password"] = request.db_password
init_config["db_name"] = request.db_name
init_config["is_init"] = True init_config["is_init"] = True
init_success = await init_tortoise(request.db_type, init_config)
if init_success:
await save_init_config(init_config) await save_init_config(init_config)
return InitStatusResponse(data=True) return InitStatusResponse(data=True)
return InitStatusResponse(success=False, message="初始化数据库失败")
except Exception as e:
return InitStatusResponse(success=False, message=str(e))
return app return app
app = create_app() app = create_app()
app.logger = logging.getLogger("workflow")
app.logger.setLevel(logging.INFO)
if __name__ == "__main__": if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8080, reload=True) uvicorn.run("main:app", host="0.0.0.0", port=8080, reload=True)

View File

View File

@ -0,0 +1,2 @@
from .system import *
from .user import *

View File

@ -0,0 +1,20 @@
from tortoise import fields
from tortoise.models import Model
class BaseModel(Model):
id = fields.IntField(pk=True)
create_time = fields.DatetimeField(auto_now_add=True)
update_time = fields.DatetimeField(auto_now=True)
def json(self, del_columns=None):
user_json = dict(self)
if del_columns is not None:
for column in del_columns:
try:
del user_json[column]
except Exception:
pass
return user_json
class Meta:
abstract = True

View File

@ -0,0 +1,10 @@
from tortoise import fields
from .system import BaseModel
class User(BaseModel):
username = fields.CharField(max_length=50, unique=True)
password = fields.CharField(max_length=128)
level = fields.IntField(default=1, null=True, description="0:超级用户 1:普通用户")
class Meta:
table = "tb_users"

View File

View File

@ -17,4 +17,4 @@ class InitConfigRequest(BaseModel):
class InitStatusResponse(BaseResponse): class InitStatusResponse(BaseResponse):
data: bool = False data: dict | bool = False

View File

@ -1,2 +1,4 @@
fastapi==0.116.1 fastapi==0.116.1
uvicorn==0.35,0 uvicorn==0.35.0
tortoise-orm==0.25.1
aiomysql==0.2.0