由于Fastai 是个python异步web框架,所以配合tortoise-orm 异步orm会编写异步,如果你本质使用fastapi 异步写法,orm如果用的sqlachemy 同步写法,其实操作数据库的时候还是同步的,当然sqlalchemy 有异步的扩展库 SQLAlchemy-Asyncio 可以进行实现配置,今天说的是另外一个天生支持异步orm的tortoise-orm库结合fastapi 配置 和apscheduler 定时任务的配置
一、fastapi和tortoise-orm的配置
先设置tortoise-orm 的配置app中的models, 这里的apps 是项目根目录下的包,apps 是多个应用,每个应用有models 数据库模型,然后把这些模型加载到tortoise-orm配置中
APP_MODELS = [
'apps.users.models',
'apps.project.models',
'apps.interface.models',
'apps.scenes.models',
'apps.task.models',
'apps.cronjob.models',
'apps.bugs.models'
]
#### TORTOISE_ORM配置
TORTOISE_ORM = {
'connections': {
'default': {
'engine': 'tortoise.backends.mysql',
'credentials': DATABASE
},
},
'apps': {
'models': {
'models': ['aerich.models', *APP_MODELS],
'default_connection': 'default',
},
}
}
在main.py 项目运行主文件程序中 注册app fastapi 实例
app = Fastapi()
app.include_router(user_router,prefix="/api/users",tags=['用户模块'])
#注册tortoise-orm 模型和app实例
register_tortoise(
app,
config=settings.TORTOISE_ORM,
modules={'models': ['models']},
generate_schemas=True,
add_exception_handlers=True,
)
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if __name__ == '__main__':
uvicorn.run(app='main:app', port=9000, reload=True)
这里是配置好了fastapi 和tortoise-orm的配置已经配置好了 然后可以写接口了
api.py # 接口层面 TestProject 是你的数据库orm模型
@pro_router.get('/projects/', tags=['项目管理'], summary='项目列表')
async def all_project_list():
data = await TestProject.all()
return data
接下来配置数据apscheduler定时任务持久化存储
scheduler_client.py
from typing import Any
import settings
from settings import DATABASE
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore
from apscheduler.executors.asyncio import AsyncIOExecutor
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from tortoise import Tortoise
from apps.utils.log import logger
class SchedulerClient:
def __init__(self):
self._schedule = None
def config_scheduler(self):
# 配置调度器和数据库连接
self._schedule = AsyncIOScheduler(
jobstores={
'default': SQLAlchemyJobStore(
url=f'mysql+pymysql://{DATABASE["user"]}:{DATABASE["password"]}@{DATABASE["host"]}:{DATABASE["port"]}/{DATABASE["database"]}',
tablename="task_job"
)
},
executors={
'default': AsyncIOExecutor(),
'threadpool': ThreadPoolExecutor(20),
'processpool': ProcessPoolExecutor(10)
},
job_defaults={
'coalesce': False,
'max_instances': 10
},
timezone='UTC'
)
# 初始化Tortoise-ORM
logger.info("开始启动定时任务服务.....")
self._schedule.start()
logger.info("定时任务服务启动成功.....")
async def init_tortoise(self):
await Tortoise.init(
db_url=f'mysql://{DATABASE["user"]}:{DATABASE["password"]}@{DATABASE["host"]}:{DATABASE["port"]}/{DATABASE["database"]}',
modules={
'models': ['aerich.models', *settings.APP_MODELS]} # 修改为你的models路径
)
await Tortoise.generate_schemas()
def __getattr__(self, name: str) -> Any:
return getattr(self._schedule, name)
def __getitem__(self, name: str) -> Any:
return self._schedule[name]
def __setitem__(self, name: str, value: Any) -> None:
self._schedule[name] = value
def __delitem__(self, name: str) -> None:
del self._schedule[name]
schedule = SchedulerClient()
# 只允许导出 schedule 实例化对象
__all__ = ["schedule"]
在fastapi main.py文件中 配置
from apps.utils.schedule import schedule # 因为我写的再utils包下的schedule.py文件中
app = FastAPI()
# 启动定时任务
@app.on_event('startup')
async def init_scheduler():
"""初始化"""
await schedule.init_tortoise()
schedule.config_scheduler()
# 配置路由
app.include_router(user_router, prefix='/api/users', tags=['用户鉴权'])
# 注册tortoiseORM模型
register_tortoise(
app,
config=settings.TORTOISE_ORM,
modules={'models': ['models']},
generate_schemas=True,
add_exception_handlers=True,
)
# 加载中间件
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
if __name__ == '__main__':
uvicorn.run(app='main:app', port=9000, reload=True)
# 这样apscheduler和tortoise-orm配置成功了注意由于apcheduler 是通过SQLAlchemyJobStore存储的,而且apscheduler 是支持sqlalchemy orm的所以你的安装下载sqlalchemy 库和pymysql