Files
zt-closet-backend/.codebuddy/plans/扁平化迁移脚本目录结构_11e4276d.md
T
2026-09-11 01:41:52 +08:00

5.6 KiB
Raw Blame History

name, overview, todos
name overview todos
扁平化迁移脚本目录结构 把 pkg/migration/migrations/*.sql 上移一层到 pkg/migration/*.sql,embed 改为 *.sql + iofs.New(fs, "."),并删除根目录多余的空占位目录 migrations/,同步更新 README 与验证。
id content status
flatten-sql 将 32 个迁移 SQL 上移到 pkg/migration 并删除空的 migrations 子目录 completed
id content status dependencies
fix-embed 修改 migration.go 的 embed 模式与 iofs 源路径为当前目录 completed
flatten-sql
id content status
clean-root-dir 删除仓库根空的 migrations 占位目录 completed
id content status dependencies
sync-readme 同步 README 中所有 pkg/migration/migrations 路径引用 completed
fix-embed
id content status dependencies
verify-build 编译与 go vet 校验,并用临时测试确认 embed 源可解析(验证后删除) completed
fix-embed
sync-readme
id content status dependencies
review-paths 用 [subagent:code-explorer] 复核目录结构与路径引用无残留 completed
verify-build

产品概述

调整已实现的数据库迁移目录结构:去掉 pkg/migration/migrations/ 这一层多余嵌套,将版本化 SQL 直接放在 pkg/migration/ 下,并清理仓库根已失效的 migrations/ 占位目录;迁移入口 cmd/migrate 保留不动。

核心功能

  • SQL 目录扁平化:32 个迁移脚本(000001~000016 的 up/down 配对)上移一层至 pkg/migration/,文件名与内容完全不变,删除空的 migrations/ 子目录
  • embed 路径适配:改为 //go:embed *.sql + iofs.New(migrationFS, "."),迁移脚本与 migration.go 同级
  • 清理根目录:删除仓库根已无引用的空占位目录 migrations/(sql/、scripts/、docs/ 保持不变)
  • 文档同步:README 目录树与「准备数据库」章节中的 pkg/migration/migrations 路径全部改为 pkg/migration
  • 迁移能力不变:Up/Down/Steps/Version/Force API、cmd/migrate 子命令、22 张表 SQL 内容均保持不变

技术栈

  • Go 1.27,模块 git.lzcwy.cn/zhengchiliu/zt-closet-backend
  • github.com/golang-migrate/migrate/v4 v4.19.1(database/mysql 驱动 + source/iofs 源)
  • github.com/go-sql-driver/mysql v1.10.0

实现方案

采用「脚本与代码同级」的扁平布局://go:embed *.sql 把同目录 SQL 打进 embed FS,iofs.New(migrationFS, ".") 以当前目录作为 golang-migrate 源根目录,文件名 00000N_xxx.up.sql / .down.sql 保持 golang-migrate 规范不变。

关键决策:

  1. 去掉源子目录而非保留:iofs 源只需一个目录根,SQL 与 migration.go 同级时路径最短、引用最少,且不损失任何能力(golang-migrate 按文件名而非目录识别版本)。
  2. //go:embed *.sql 只嵌入 SQL:embed FS 中不会出现 .go 文件,避免 iofs 源扫描到无关文件。
  3. 保留 cmd/migrate:用户已确认接受 Go 标准布局;独立二进制使迁移不依赖主服务的 Redis/COS/支付等初始化。
  4. 不改文件名与内容:避免已应用环境的版本号/校验和变化,保证迁移历史兼容。

实现要点(防回归)

  • migration.go 中 migrationsDir 常量改为 "." 并更新注释(迁移脚本与本文件同级);iofs.New(migrationFS, migrationsDir) 调用不变。
  • 文件名保持 00000N_xxx.up.sql / 00000N_xxx.down.sql,不要重命名或改版本号。
  • 验证用临时测试文件放在 pkg/migration 下(仅 iofs.New + src.First(),不连数据库),验证后必须删除。
  • 不要改动 cmd/migrate/main.go、SQL 内容与迁移包对外 API。
  • 不连接真实数据库:configs/config.yaml 的 MySQL 为内网地址,且该文件第 2 行 Domain: * 为非法 YAML(用户本地配置,本次不处理)。

架构设计

flowchart LR
    A["cmd/migrate/main.go<br/>up/down/steps/version/force"] --> B["pkg/setting<br/>读取 Mysql 段"]
    B --> C["pkg/migration.Run<br/>DSN multiStatements=true"]
    C --> D["iofs.New(embed FS, .)"]
    D --> E["pkg/migration/*.sql<br/>000001~000016 up/down"]
    C --> F["mysql.WithInstance(*sql.DB)"]
    E --> G["migrate.NewWithInstance"]
    F --> G
    G --> H["schema_migrations"]

目录结构

pkg/migration/
├── migration.go              # [MODIFY] //go:embed 由 migrations/*.sql 改为 *.sql;migrationsDir 常量由 "migrations" 改为 ".";
│                             #          Up/Down/Steps/Version/Force/Run 与 DSN 拼装逻辑不变
├── 000001_create_users.up.sql            # [MOVE] 由 migrations/ 上移,内容不变
├── 000001_create_users.down.sql          # [MOVE]
├── ...(000002~000016 的 up/down,共 32 个文件)[MOVE]
└── migrations/               # [DELETE] 空目录,扁平化后删除
migrations/                   # [DELETE] 仓库根空占位目录,已无引用
README.md                     # [MODIFY] 目录树:pkg/migration 去掉 migrations 子层;
                              #          「准备数据库」章节与 sql/ 占位说明中的 pkg/migration/migrations 改为 pkg/migration

Agent Extensions

SubAgent

  • code-explorer
  • Purpose:扁平化完成后复核 pkg/migration/ 目录结构与 README 中的路径引用,确认 migrations/ 子目录与根占位目录已消失、无遗留 pkg/migration/migrations 文本引用、32 个 SQL 文件齐全且 up/down 配对完整
  • Expected outcome:输出路径引用与文件清单核查结果,确保无残留旧路径