ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

OpenProject 数据库迁移实战指南:Rails Migration 约定、常用命令与 Squashing 压缩机制

OpenProject 数据库迁移实战指南:Rails Migration 约定、常用命令与 Squashing 压缩机制 OpenProject 数据库迁移实战指南Rails Migration 约定、常用命令与 Squashing 压缩机制【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject本篇技术指南聚焦 OpenProject 的数据库层开发与运维实践涵盖db/CLAUDE.md约定的迁移代码规范、本地与 Docker 环境下的迁移/回滚/填充命令、config/database.yml的 Docker 使用禁忌并深入剖析 OpenProject 在主版本之间对历史迁移进行 Squashing 压缩的机制与验证方法。读完本文你将掌握在 OpenProject 仓库中安全编写、执行、压缩与校验数据库迁移的完整能力。迁移代码规范遵循 Rails 约定并在主版本间 SquashOpenProject 的数据库迁移遵循 Rails 迁移Migration约定每次 schema 或数据变更都应通过独立、带时间戳的迁移文件表达并放置在db/migrate/目录下。仓库中现存的大量迁移文件如20240123151246_create_good_jobs.rb、20260330100000_create_work_package_semantic_ids.rb、20260831120000_migrate_version_to_target_versions_in_type_variants.rb等就是这一约定的直接体现。与普通 Rails 项目不同的是OpenProject 会在每个主版本发布之间对迁移进行 Squashing压缩合并。其动机在于迁移往往同时包含结构变更与数据变更而数据迁移常依赖外部库或应用代码随着版本演进这些依赖可能变化导致历史迁移难以维护且 bug 难以排查。通过压缩OpenProject 可以不再维护过时的旧迁移。该策略的完整说明见 docs/development/migrations/README.md。版本化规则必须逐主版本升级Squashing 带来了一个关键约束每个主版本发布时迁移会被压缩因此一个安装实例必须先迁移到最近的主版本才能继续迁移到当前版本。例如要迁移到 OpenProject 16.x必须先存在一个 OpenProject 15.x 的安装当前仓库中聚合迁移文件1000016_aggregated_migrations.rb的存在即对应这一代版本。并非所有迁移都会被压缩——最近一个主版本内新增的迁移保持原样留待后续发布时再压缩。常用迁移命令本地开发与 Docker 环境db/CLAUDE.md明确给出了两类执行环境下的命令下面结合仓库实际情况逐一说明。本地开发环境bundle exec rails g migration MigrationName # 生成一个迁移 bundle exec rails db:migrate # 执行迁移 bundle exec rails db:rollback # 回滚最近一个迁移 bundle exec rails db:seed # 填充示例/种子数据rails g migration生成的迁移文件会落在db/migrate/下并自动获得时间戳前缀遵循 Rails 默认命名与格式可参考db/migrate/中任意现有文件。rails db:rollback默认回滚最近一次迁移若当前数据库 schema 是经由压缩后的聚合迁移建立的回滚会走SquashedMigration#down其实现为直接抛出ActiveRecord::IrreversibleMigration提示使用对应主版本的安装进行降级详见 db/migrate/migration_utils/squashed_migration.rb。rails db:seed执行 db/seeds.rb 中的种子数据逻辑。本地数据库连接通过 config/database.yml.example 配置development 库默认openproject_development连接池pool: 100test 库openproject_testpool: 5production 库openprojectpool: 20均使用 PostgreSQL 适配器与 unicode 编码。Docker 环境bin/compose exec backend bundle exec rails db:migrate # 执行迁移 bin/compose exec backend bundle exec rails db:seed # 填充数据在 Docker 部署下迁移与种子填充通过bin/compose exec backend进入后端容器内执行而不是在宿主机直接运行。这与 docker-compose.yml 定义的 backend 服务结构对应确保迁移在与应用一致的环境中运行。关键注意Docker 下config/database.yml必须不存在db/CLAUDE.md中的CRITICAL提示是实践中最容易踩坑的一点CRITICAL:config/database.ymlmust NOT exist when using Docker (rename or delete it)当使用 Dockerbin/compose运行时仓库根目录下的config/database.yml不能存在需要将其重命名或删除。原因在于容器环境数据库主机、账号、密码等由 Docker Compose 的环境变量与配置注入管理若本地存在database.yml其硬编码的连接信息会覆盖容器注入的配置导致后端容器连接到错误的主机或凭据而启动/迁移失败。仓库仅提供 config/database.yml.example 作为非 Docker 场景的参考模板本身并不提交database.yml到版本库也印证了这一点。深入原理Squashing 压缩机制与源码实现为了让上文“主版本间压缩迁移”的原则落地OpenProject 在常规 Rails 迁移之上实现了一套完整机制核心实现在 docs/development/migrations/README.md 与 db/migrate/migration_utils/squashed_migration.rb 中。聚合迁移文件的组成每个主版本对应一个聚合迁移文件例如核心应用的 db/migrate/1000016_aggregated_migrations.rb各模块也有自己的聚合文件。这些文件继承自SquashedMigration其本身继承自ActiveRecord::Migration[8.0]并通过四个声明式入口描述目标 schemaextensions列表声明需要创建的数据库扩展如Extensions::BtreeGist、Extensions::PgTrgm、Extensions::Unaccent、Extensions::VersionNameCollation。扩展会最先被加载以便后续表可以引用它们。以 db/migrate/extensions/pg_trgm.rb 为例它声明extension pg_trgm并在扩展缺失时输出安装postgresql-contrib模块的警告提示。tables列表列出需要创建的全部表含列、索引、约束等。每张表一个专属类存放于 db/migrate/tables/模块对应迁移位于模块内部并遵循“表文件应与模型文件同处一个模块/核心”的放置原则。以 db/migrate/tables/announcements.rb 为例Tables::Announcements定义了text、show_until、active等列及(show_until, active)联合索引。squashed_migrations列表列出本文件压缩掉的迁移名仅包含本版本压缩的迁移此前已被压缩的不再列出。聚合文件内通过squashed_migrations *%w[...]逐条引用如1000016_aggregated_migrations.rb中的squashed_migrations列表以1000015_aggregated_migrations开头随后是20241030154245_create_project_life_cycles、20241119131205_create_reminders等被压缩的迁移见 db/migrate/1000016_aggregated_migrations.rb。modifications块插件可以通过modifications段修改某张表这是例外用法适用于功能强归属该模块且不被其他模块使用的场景见 squashed_migration.rb 的类方法定义。文件命名与依赖顺序聚合迁移文件名以10[两位顺序号]0[压缩版本号]为时间戳前缀例如1000016_aggregated_migrations.rb顺序号用于解析依赖例如某模块向核心表添加外键则该模块必须排在核心之后运行同时保证迁移名唯一。压缩版本号则标识其对应的主版本。压缩执行流程SquashedMigration#up调用Migration::MigrationSquasher.squash(self.class.squashed_migrations, self.class.minimum_version)在其块内依次创建扩展、创建表、执行modifications见 squashed_migration.rb。minimum_version类属性默认值为16见 squashed_migration.rb用于down时提示用户降级所需的 OpenProject 版本。其余辅助工具列操作、权限重命名、设置重命名、typed_dag 等集中在 db/migrate/migration_utils/ 目录。发布新主版本时的压缩步骤docs/development/migrations/README.md给出了完整的压缩操作清单核心步骤包括检查SquashedMigration上的 Rails 版本若两个 OpenProject 版本间 Rails 升级需同步修改ActiveRecord::Migration[RAILS_VERSION]超类引用并验证其对目标结构的影响。重命名既有聚合迁移将时间戳改为反映上一主版本例如发布 OP 17.0 时把db/migrate/1000015_aggregated_migrations.rb重命名为1000016_aggregated_migrations.rb新模块首次获得聚合文件时需确保不与既有顺序号冲突。删除被压缩的迁移压缩截至上一主版本的最后一个补丁版本删除时以被压缩文件为清单逐条处理。创建/调整表类将删除迁移中的建表与改表逻辑移入 db/migrate/tables/ 对应表文件Tables::Xxx类列归属模块时可放入模块聚合文件的modifications段。创建/调整扩展类将索引与排序规则等扩展移入 db/migrate/extensions/ 对应扩展文件。忽略数据变更聚合文件只描述数据库结构原迁移中移动存量数据的数据变更代码不再需要。清理失去引用的代码删除只被被压缩数据迁移引用的后台任务、库、服务或 scope。更新最低版本提高SquashedMigration类的minimum_version反映新的迁移要求如 OP 16 要求 15、OP 17 要求 16。验证压缩是否引入 schema 变化压缩过程完成后需要通过结构对比与数据对比双重验证具体步骤同样记录在 docs/development/migrations/README.md。结构验证压缩前先执行rails db:drop db:create db:migrate生成db/structure.sql并另存为structure_unsquashed.sql完成压缩后再次执行相同命令生成新的structure.sql用diff对比两份文件应无差异。若存在已知缺憾可用独立迁移另行修复。数据验证找一份含数据的数据库先pg_dump --column-inserts -U [user_name] -d [database_name] [database_name]-orig.sql导出原库并用psql [another_database_name] [database_name]-orig.sql载入切到压缩前的提交如 dev 分支执行rails db:migrate后导出[database_name]-dev.sql再rails db:drop db:create重建切到压缩后的提交重新载入原 dump 并rails db:migrate导出[database_name]-squashed.sql最后git diff对比两份导出确保数据一致。特殊处理good_job 的迁移文件一个值得注意的例外是 good_jobOpenProject 的后台任务队列实现。good_job 升级时会依据“是否存在预期名称的迁移文件”来重新生成迁移因此其迁移文件不能被删除正确做法是将其内容清空并把结构移入tables类与普通 Squashing 处理方式相同。仓库db/migrate/下可见20240123151246_create_good_jobs.rb、20240123151247_create_good_job_settings.rb等一整套 good_job 相关迁移以及 db/migrate/tables/good_jobs.rb、good_job_batches.rb 等对应表类正是该处理策略的落地证据。小结OpenProject 的数据库层既遵循标准 Rails 迁移约定又在主版本间引入 Squashing 压缩机制来控制迁移维护成本日常开发使用bundle exec rails g migration / db:migrate / db:rollback / db:seedDocker 环境通过bin/compose exec backend bundle exec rails ...执行并严禁存在config/database.yml而涉及主版本升级时则需要依据聚合迁移文件extensions/tables/squashed_migrations/modifications与SquashedMigration的实现完成压缩、删除、表类迁移与最低版本更新并通过结构 diff 与数据 dump 对比验证结果。【免费下载链接】openprojectOpenProject is the leading open source project management software for product, project and portfolio management. A powerful Jira alternative with agile planning, issue tracking, roadmaps, Gantt charts, time tracking, collaboration features, and more. Available on premises or in the cloud. ⭐ Star us on GitHub项目地址: https://gitcode.com/GitHub_Trending/op/openproject创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表