# Django部署云托管使用migration
Django 有一套 ORM,所以在使用 Django 开发项目时,我们不需要写SQL语句和数据库交互,直接通过 ORM 将类的操作转换成SQL操作。
参与上述步骤的内容主要有如下几种:
- Models:也就是我们在开发项目所定义的数据模型。
- Migrations:记录Model从初始状态演进为最终状态的步骤
- django_migrations:数据库中的表,记录执行了哪些步骤,为的是后续执行的时候就只需要执行没有执行的步骤。
当你的 Model 发生变化时,就可以执行 migration 来将 Model 与数据库 Table 同步,这个同步过程主要分两步:
python manage.py makemigrations
,生成 migrations,将修改前的 Model 和修改后的 Model 对比,找出不同点,然后根据不同点找出同步的步骤,生成 migrations 文件。python manage.py migrate
,根据 migrations 文件执行SQL语句,操作数据库的表结构,如果数据库之前有操作过(不是空表),则根据 django_migrations 表中记录,只执行没有执行过的步骤。
# migration 应该如何正确执行?
migration 操作涉及数据库的SQL语句执行,所以我们在执行操作的时候,一定首先要判断执行的环境能不能连接数据库。
云托管的数据库有两个地址,一个是内网地址(只有同一个环境内的服务可以访问),一个是外网地址(有网的地方就能访问)。
# 1. Dockerfile
中 RUN
命令
很多同学会直接在构建时执行 CMD 命令,在这里需要注意的是,构建环境(包括本地)都不在数据库VPC内网中。
也就是说,你在这里执行 migration
,内网地址是行不通的,你只能使用外网地址才能完成。
我们不建议这种用法,如果你的 migration
操作非常多的时候,因为操作耗时变长,相应的会增加构建耗时。
# 2. 本机直接执行 migration 操作
通过数据库外网地址连接,完成 migration
操作。
这种方法虽然简单,但如果说新旧版本依赖的数据库结构不同,有可能会引起业务故障。所以一般来说在线的生产环境,尽量不要在新版服务未就位的情况下,擅自变动数据库结构。
# 3. 启动服务时执行 migration 操作
在 Dockerfile
的 CMD
或 ENTRYPOINT
命令中,集成 migration
操作,服务容器启动后即开始 migration
过程。
可以写一个sh脚本,将项目启动命令和 migration
操作写入。然后直接 CMD
此脚本。
这种方式有几个点需要注意:
- 多个实例同时创建出来时,需要注意竞争处理,不要发生多个实例同时
migration
操作。 - 尽可能优化
migration
操作,时间不要太长,可以通过重新生成 migrations 文件,改变 django_migrations 记录值来实现。 migration
操作过程如果较长时,需要注意项目的兼容性,比如直接返回升级中字样。
# 4. 直接进入Webshell,完成 migration 操作
如果你为了安全考虑,不想打开数据库外网地址。可以通过任意服务的实例 webshell 进入,执行 migration
操作,webshell进入的实例都是同数据库VPC内网环境。
你可以专门构建一个用户管理的服务,预先安装所以必须的程序,后续操作的时候,直接拉起这个管理服务,进入websell操作任务即可。