Django迁移CI优化
项目描述
django-migrations-ci
在CI中重用数据库状态。仅在更改时在CI测试上运行迁移。
迁移很慢,但出于测试原因,您必须在CI上运行它,因此避免在数据库状态已经测试的情况下运行它们。
安装
使用pip安装包
pip install django-migrations-ci
将django_migrations_ci
添加到Django设置中的INSTALLED_APPS
。
INSTALLED_APPS = [
..., # other packages
"django_migrations_ci",
]
如何使用
命令migrateci
执行所有迁移并保存转储文件migrateci-*
。
如果这些文件已在磁盘上存在,它们将用于准备数据库而无需再次运行所有迁移。
工作流程
这就是“运行测试”CI作业应该如何工作。
./manage.py migrateci
./manage.py test --keepdb
它也可以与pytest-django
一起作为插件工作
pytest --migrateci --reuse-db
与其配合使用的方式是配置默认的pytest addopts
,使用--migrateci --reuse-db
以不重新创建数据库的方式运行。当您想要重新创建时,运行具有优先级的pytest --create-db
,该优先级高于--reuse-db
。
并行测试
./manage.py migrateci --parallel $(nproc)
./manage.py test --keepdb --parallel $(nproc)
使用pytest-django的并行测试
pytest --migrateci --reuse-db --parallel $(nproc)
也请参阅并行测试的数据库名称。
设置
MIGRATECI_STORAGE="django.core.files.storage.FileSystemStorage"
文件存储类。 django-storages 包实现了许多后端。
将缓存文件保存到外部存储可以让库重用部分迁移。当你编写一个新的迁移时,它将尝试获取一个不包含最后一个迁移的缓存并从中加载,仅运行新的迁移。
一个S3示例,但它适用于任何自定义后端
from storages.backends.s3boto3 import S3Boto3Storage
class MigrateCIStorage(S3Boto3Storage):
bucket_name = "mybucket-migrateci-cache"
region_name = "us-east-1"
object_parameters = {
"StorageClass": "REDUCED_REDUNDANCY",
}
MIGRATECI_LOCATION=""
文件存储API有一个位置参数,所有后端都以某种方式使用。
如果没有定义存储,它默认为~/.migrateci
,以便于本地工作。
MIGRATECI_PYTEST=False
pytest-django
包使用自定义测试数据库名称。
如果你使用它并且没有更改它们的默认固定值,只需使用MIGRATECI_PYTEST=True
。
MIGRATECI_PARALLEL=None
在测试之前,Django将执行一个数据库中的所有迁移,并将其克隆以便能够运行并行测试。使用MIGRATECI_PARALLEL="auto"
创建每个进程一个数据库,或者使用MIGRATECI_PARALLEL=4
定义确切的进程数。
它支持Django测试和pytest-xdist的工作方式。
MIGRATECI_DEPTH=1
这就是我们决定使用哪个迁移缓存的方法。
首先,它会尝试找到一个包含所有迁移文件的缓存,但在某些情况下这是不可能的,比如当你刚刚推送了一个新的迁移。
对于MIGRATECI_DEPTH=1
,它会为安装的每个Django应用程序逐个删除一个迁移,并检查是否存在某些缓存的迁移。它支持最常用的用例,并且速度合理。
更大的值会导致成本较高的操作,它会一次删除N个迁移并检查是否存在缓存的迁移。这是每个Django应用程序的组合。例如,对于10个应用程序,它将进行最多10^N次检查,并执行一些哈希操作。
命令行设置
以下所有设置都可以通过命令行参数定义。
manage.py migrateci [-h] [-n PARALLEL] [--storage STORAGE_CLASS] [--location LOCATION]
[--pytest] [--depth DEPTH] [-v {0,1,2,3}]
options:
-h, --help show this help message and exit
-n PARALLEL, --parallel PARALLEL
--storage STORAGE_CLASS
--location LOCATION
--pytest
--depth DEPTH
--checksum Prints the current checksum and exits.
-v {0,1,2,3}
本地迁移缓存
作为此包的扩展,在本地开发期间也可以使用相同的策略。它默认将文件缓存到~/.migrateci
。
./manage.py migrateci --parallel $(nproc)
./manage.py test --keepdb --parallel $(nproc)
为什么迁移速度慢?
Django迁移速度慢是因为每次迁移都需要重新创建状态以及其他Django内部魔法。
过去,我试图在Django核心中优化这一点,但了解到这是一个运行中的问题。
支持的数据库
- mysql
- postgresql
- sqlite3
Django默认运行sqlite3测试作为内存数据库,并且因为migrateci
在不同的进程中运行,所以不工作。请向设置中添加测试数据库名称,如sqlite测试设置。
Django支持oracle,但这里没有实现导出函数。
并行测试的数据库名称
Django测试框架有一个--parallel N
标志,可以通过N个并行进程进行测试,数据库名称从1到N。
- 在sqlite3上,一个
db.sqlite3
会生成db_N.sqlite3
文件。 - 在其他数据库上,一个
db
会生成test_db_N
。
Pytest pytest-django
使用pytest-xdist
进行并行支持,数据库名称从0到N-1。
- 在sqlite3上,一个
db.sqlite3
会生成db.sqlite3_gwN
文件。 - 在其他数据库上,一个
db
会生成test_db_gwN
。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪一个,请了解有关安装包的更多信息。