FastAPI 操作数据库

发布时间: 2022-01-20 17:20:25 作者: 大象笔记

原本想使用 python orator 这个 ORM 方案。 但是发现搜索 FastAPI ORM 的方案,并没有人提到 orator。 我主要是担心第一次使用 FastAPI 这个异步框架,再配合上 orator 这类异常小众的 ORM,会不会踩坑。

所以,还是优先使用官方推荐的方案。至于是不是 ORM,不重要。

encode/databases

FastAPI 官方文档里推荐的异步操作数据库的方案是 encode/databases。

参考:

https://fastapi.tiangolo.com/advanced/async-sql-databases/

不过里面的示例代码都是 databases 配合 SQLAlchemy 使用,我觉得 SQLAlchemy 的学习成本过高, 非常不值得。用 RAW 足够满足我目前的简单需求。

Raw queries 的使用方式可以参考 databases 的官方文档:

https://www.encode.io/databases/database_queries/

安装 databases 依赖

pip install databases

可以看到,在安装 databases 时,自动安装了 SQLAlchemy 依赖。。。

由于我用的是 MySQL 数据库,这里需要再安装 MySQL driver。

pip install databases[mysql]

数据库连接的建立与断开

# Use a connection pool of between 5-20 connections.
# database = Database('mysql://localhost/example?min_size=5&max_size=20')
database = databases.Database('mysql://user:password@localhost:3306/db')


@app.on_event("startup")
async def startup():
    await database.connect()


@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

数据库连接池

这个默认的连接数是多少?我看 SQLAlchemy 默认是 5 个,但是不知道 databases 的默认值是多少。

数据库配置参数从 .env 文件读取

由于我的主站是用 laravel 写的,所以数据库的配置都是放在 laravel 项目的 .env 配置文件中, 为了避免存在多份配置文件,所以需要能够从 FastAPI 读取其他目录下的 .env 文件。

https://fastapi.tiangolo.com/advanced/settings/#reading-a-env-file

创建软链接的方式,将 laravel 项目的 .env 文件链接过来,然后 FastAPI 在当前目录读取是否可行。

.env snippet 统一设置 key 的名称。

如果未来还有其他配置项,实在不行,就复制一份到当前目录下,也未尝不可。 然后参考 laravel 的做法,不降 .env 放入 git 代码管理,存在一份 .env.example 模板就行了。

处理数据库连接异常

主要是为了方便本地调试,在没有测试数据,或者本地没有数据库的情况下,依然可以调试界面及基本功能。

@app.on_event("startup")
async def startup():
    try:
        await database.connect()
    except Exception as e:
        logger.info("fail to connect db")
        logger.info("type error: " + str(e))

至于数据库读取的相关功能,我目前的项目直接在线上服务器调试也未尝不可。

读取数据

async def get_app_info(name):
    query = "SELECT * FROM kv WHERE `key` = :name"
    result = await database.fetch_one(query=query, values={"name": name})
    logger.info(result)
    # TODO
    # 判断记录不存在的情况,新建一条记录,方便后台编辑
    return result

参考

我是一名山东烟台的开发者,联系作者