from fastapi import FastAPI
from tortoise.contrib.fastapi import register_tortoise
from app.config import config
class GetDB(object):
def _get_orm_base_conf(self, apps: dict) -> dict:
return {
'connections': {
'default': {
'engine': 'tortoise.backends.mysql',
'credentials': {
'host': config.MYSQL_HOST,
'port': config.MYSQL_PORT,
'user': config.MYSQL_USERNAME,
'password': config.MYSQL_PASSWORD,
'database': config.MYSQL_DATABASE,
'minsize': 1,
'maxsize': 5,
'charset': 'utf8mb4'
}
}
},
'apps': apps,
'use_tz': False,
'timezone': 'Asia/Shanghai'
}
@property
def orm_link_conf(self) -> dict:
orm_apps_settings = {
'models': {
'models': [
'app.models.__init__'
],
'default_connection': 'default',
},
}
return self._get_orm_base_conf(orm_apps_settings)
ORM_LINK_CONF = GetDB().orm_link_conf
def init_db(app: FastAPI):
"""init and bind tortoise-orm"""
register_tortoise(
app,
config=ORM_LINK_CONF
)
GetDB类的属性方法orm_link_conf中 models表示是自己的数据库model的项目地址。fastapi 中创建app对象的时候,将 init_db 方法绑定到app:
def create_app():
app = FastAPI(
debug=True,
title=config.TITLE,
description="",
version=config.VERSION,
docs_url=config.DOCS_URL,
openapi_url=config.OPENAPI_URL,
redoc_url=None,
openapi_tags=tag_metadata,
)
app.include_router(
api_router,
prefix=config.API_PREFIX,
)
init_db(app) # 绑定数据库
register_exception(app) # 注册捕获异常信息
register_cors(app) # 跨域设置
register_middleware(app)
return app
数据库model, 以Role为例
class Role(Model):
"""权限-角色"""
name = fields.CharField(max_length=200, unique=True, description="角色名", default='')
permission = fields.ManyToManyField("models.Permission", related_name='related_permission_role',
description="权限-角色关联权限")
addtime = fields.DatetimeField(description="添加时间", default=datetime.datetime.now())
await Role.create(name="审计员")
也可以写成
await Role.create(**dict(name="管理员"))
await Role.filter(pk=1).update(**dict(name="管理员"))
role = await Role.filter(pk=1).first()
role.name = "管理员"
await role.save()
await Role.filter(pk=1).delete()
role = await Role.filter(pk=1).first()
await role.delete()
1.查询所有
roles = await Role.filter().all()
2.查询单条记录
roles = await Role.filter().first()
3.记录是否存在
await Role.filter(name='管理员').exists()
4.将查询的结果转换为列表
roles = await Role.filter().all().values()
5.查询条件
not
in- 检查字段的值是否位于传递列表中
not_in
gte- 大于或等于传递的值
gt- 大于传递的值
lte- 低于或等于传递的值
lt- 低于传递值
range- 介于和给定两个值之间
isnull- 字段为空
not_isnull- 字段不为空
contains- 字段包含指定的子字符串
icontains- 不区分大小写contains
startswith- 如果字段以值开头
istartswith- 不区分大小写startswith
endswith- 如果字段以值结尾
iendswith- 不区分大小写endswith
iequals- 区分大小写等于
roles = await Role.filter(name__icontains="abc").all()
6.group by , order by, sum, count , limit, offset 等
roles = await Role.filter().annotate(count=Count("id")).group_by("name").limit(10).offset(10).values()
order_by如果需要排序的话可以直接排序
根据id 升序排列
order_by("id")
根据id降序排列
order_by("-id")
7.对时间进行格式化
from pypika import CustomFunction
class TruncMonth(Function):
database_func = CustomFunction("DATE_FORMAT", ["name", "dt_format"])
roles = await Role.filter().annotate(date=TruncMonth('addtime', '%Y-%m-%d'), count=Count("id")).group_by("date").values("date", "count")
注意 时间格式化 对应的 tortoise-orm 版本要 0.17以上 0.16.16 会报错