最近在使用Fastapi编写代码时,结合tortoise-orm编写数据库的orm模型,实现关系型数据库的交互操作。Tortoise ORM 是一个受 Django 启发的易于使用的异步 ORM(对象关系映射器),其功能与Django的orm非常类似。
在编写完数据库模型以后,tortoise-orm会根据你的orm模型为你生成对应的数据库表,但是如果你后续想更改某个数据表的结构,比如添加,修改某些表字段,此时tortoise-orm无法为数据表进行你所需要的操作。我们可以借助第三方库Aerich进行数据库的迁移,下面示例演示在fastapi里面使用Aerich迁移数据库。
对应版本:
python==3.11
fastapi==0.110.0
tortoise-orm==0.20.0
aerich==0.7.2
mysql版本为5.8
0、我在apps下面的sql_models下面有个模型类
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50, index=True, unique=True, description='用户名')
password = fields.CharField(max_length=100, index=True, description='密码')
1、在fastapi中配置tortoise-orm所需要注册的配置信息
tortoise_config = {
'connections': {
'default': {
'engine': 'tortoise.backends.mysql',
# 数据库的基本配置信息
'credentials': {
'host': HOST,
'port': PORT,
'user': USER,
'password': PASSWORD,
'database': DB,
'minsize': MINSIZE,
'maxsize': MAXSIZE,
'pool_recycle': POOL_RECYCLE * 3600,
}
},
},
'apps': {
'models': {
# apps.sql_models为你编写的模型类的位置,比如这个为apps下面的sql_models里面,aerich.models保持默认即可
'models': ['apps.sql_models', 'aerich.models', ],
'default_connection': 'default',
}
}
}
2、使用register_tortoise进行注册
def create_app():
application = FastAPI()
application.mount("/statics", StaticFiles(directory="statics"), name="statics")
application.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
register_tortoise(
application, # fastapi实例
config=tortoise_config, #数据库配置信息
generate_schemas=False, # 立即生成模型,这里我们设置成False,因为我们使用aerich进行生成
add_exception_handlers=True, #为DoesNotExist和IntegrityError添加一些自动异常处理程序,但是不建议在生产系统中使用,因为这可能会泄露数据。
)
return application
3、在fastapi的@app.on_event("startup")事件函数中进行数据库的迁移操作,这个函数用于定义当 FastAPI 应用启动时应该运行的函数或方法。这个事件处理函数通常用于执行应用启动时所需的初始化操作。
@app.on_event("startup")
async def create_db():
command = Command(tortoise_config=tortoise_config)
await command.init()
# await command.migrate()
await command.upgrade(run_in_transaction=True)
到了这一步基本配置信息已经完成了,现在万事俱备只欠东风了。接下来到项目的命令行终端输入一下两行命令。
aerich init -t app.tortoise_config
aerich init-db
即会在项目里面生成一个migrations/models/0_时间_init.py的初始迁移文件,有这个文件后只需重启fastapi服务就可生成对应的数据表。
讲到这里,最基本的实现了,但是最重要的还是没有出现,就是如果更改了表结构怎么重新生成迁移文件呢?
比如说我需要在上面User模型中添加一个权限字段:
permission = fields.SmallIntField(index=True, description='权限')
在你添加完以后,需要把@app.on_event("startup")事件函数中await command.migrate()注释解开,重新启动服务即可,此时你会发现migrations/models文件夹下面新增了一个文件1_时间_update.py文件(注意生成新的迁移文件后,你需要再次把wait command.migrate()部分重新注释,避免误操作生成新的迁移文件),这时你会发现已经数据表结构已经更改成功了。