codeigniter 4 的数据库迁移是结构化、可回滚、可协作的版本控制机制,非手动sql替代;需用php spark make:migration生成带时间戳前缀的文件,类名须严格匹配文件名并继承migration,命名空间须正确注册,force()可跳过顺序执行单个迁移但生产禁用,migrations表误删需手动重建并核对状态。

CodeIgniter 4 的数据库迁移不是“手动执行 SQL 脚本”的替代品,而是结构化、可回滚、可协作的版本控制机制。它本身不提供自动差异检测,也不支持从现有表反向生成迁移——所有迁移文件必须由开发者显式创建并维护。
迁移文件怎么生成和命名
用 php spark make:migration 命令生成,名称需体现意图,比如 CreateUsersTable 或 AddEmailToPosts。框架会自动加上时间戳前缀(如 20231015142230_create_users_table.php),这是执行顺序的唯一依据。
- 时间戳必须全局唯一;重复会导致
Migration runner not found或跳过执行 - 文件名中的大小写不影响逻辑,但建议用 PascalCase 保持可读性
- 不要手动修改时间戳部分,否则可能破坏依赖顺序或导致重复运行
- 迁移类名必须与文件名一致(不含时间戳),否则
spark migrate找不到类
迁移执行时为什么报错“Class not found”
常见原因是命名空间或类名不匹配。CI4 要求迁移类继承 CodeIgniter\Database\Migration,且类名必须严格对应文件名(去掉时间戳和 .php 后缀)。
- 检查
app/Database/Migrations/下的文件是否在App\Database\Migrations命名空间下 - 确认类定义为
final class CreateUsersTable extends Migration,不是class create_users_table或Create_user_table - 如果用了自定义命名空间(如
--namespace=MyApp),要确保composer.json中已注册该命名空间的自动加载路径 - 执行
composer dump-autoload后再试,尤其在新增或重命名迁移文件后
如何跳过时间戳顺序,只跑某一个迁移文件
CI4 原生命令不支持按文件路径直接执行单个迁移,但可通过自定义命令实现。官方推荐方案是新建一个 CLI 命令,调用 $runner->force() 方法。
- 核心是传入完整文件路径(含
ROOTPATH)、命名空间和数据库组,例如:$runner->force(ROOTPATH . 'app/Database/Migrations/20231015142230_create_users_table.php', 'App', 'default') - 这种方式绕过所有依赖检查和时间戳比对,仅用于调试、补漏或模块化部署
- 生产环境禁用:一旦误用,可能导致迁移状态表(
migrations)记录与实际 DB 结构不一致 - 别忘了在迁移类的
up()和down()中显式处理事务,force()不自动开启事务
迁移状态表(migrations)被删了怎么办
这个表由 CI4 自动创建,记录已执行的迁移文件和批次号。如果被误删,不能靠 spark migrate:refresh 恢复——它只会清空数据表,不会重建 migrations 表本身。
- 最稳妥方式是重新运行全部迁移:
php spark migrate:reset && php spark migrate - 若已有线上数据不能清空,需手动重建
migrations表(字段:id、version、class、group、namespace、time、batch) - 然后根据当前 DB 状态,手工插入对应已执行迁移的记录(注意
batch字段要一致,否则后续migrate:rollback会失败) - 迁移状态一旦错乱,
spark migrate:status输出就不可信,得靠人工核对app/Database/Migrations/和实际表结构
迁移的本质是“人写的代码 + 人维护的顺序”,框架只负责执行和记录。时间戳不是装饰,状态表不是可选,而是一整套协作契约的落地点——任何绕过它的操作,都得自己承担校验成本。











