CI4迁移文件必须用CLI生成,不可手写;up()/down()需调用$this->forge抽象方法而非原生SQL;Seeder仅用于开发环境预置数据,不可替代业务逻辑清理。

CI4 迁移文件必须用 CLI 生成,不能手写
CodeIgniter 4 的迁移(Migration)机制依赖严格的时间戳前缀和类名规范,手写文件极易因命名错误、命名空间缺失或方法签名不符导致 php spark migrate 报错且不提示具体原因。官方要求所有迁移文件必须通过命令行生成:
-
php spark make:migration CreateUsersTable→ 自动生成20260807025600_create_users_table.php(时间戳精确到秒) - 文件名中时间戳不可修改,否则 spark 无法识别执行顺序
- 类名必须与文件名一致(如
CreateUsersTable),且继承CodeIgniter\Database\Migration - 若已存在同名迁移文件,spark 会拒绝生成并报错 —— 此时应删掉旧文件再重试,不要改时间戳“凑数”
up() 和 down() 方法里别直接写 SQL
CI4 迁移不是 SQL 脚本容器,up() 和 down() 应调用 $this->forge 提供的抽象方法。硬写 CREATE TABLE 或 DROP TABLE 会丢失跨数据库兼容性,且在 SQLite 等驱动下可能失败。
- 正确写法:
$this->forge->addField(['id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true]]); $this->forge->addKey('id', true); $this->forge->createTable('users'); - 删除字段不能只写
$this->forge->dropColumn('users', 'old_field')—— 必须先确保该字段存在,否则报错无提示;建议在up()中加if ($this->db->fieldExists('old_field', 'users')) { ... } -
down()不是up()的逆操作:比如up()建表,down()应删表;但若up()是改字段类型,则down()应还原为原类型,而非删字段
填充器(Seeder)不能替代业务逻辑清理
Seeder 是为开发环境预置测试数据设计的,不是生产环境的数据清洗工具。你看到的“用 seeder 清理旧用户”方案,本质是把业务规则硬编码进填充器,后续无法回滚、无法审计、也无法纳入部署流程。
- Seeder 只应在
php spark db:seed时运行一次,且默认不启用 —— 必须在.env中显式设CI_ENVIRONMENT = development才能触发 - 若需清空某张表,用
$this->db->table('logs')->truncate()比delete()更快,但注意:truncate 无法触发 delete 事件,也不走模型钩子 - 真正要裁剪遗留表结构(比如删掉 30 张不用的表),别塞进 seeder —— 直接让 DBA 执行
DROP TABLE,并在项目 README.md 中记录操作清单
迁移失败后别手动删 migration_version 表记录
migration_version 表由 CI4 自动维护,记录已执行迁移的时间戳。手动删记录会导致 spark 认为某次迁移未执行而重复运行,轻则报错“Table already exists”,重则破坏数据一致性。
- 迁移失败时,先看终端输出的完整错误栈 —— 多数问题出在 forge 方法参数错误(如字段类型拼错为
'interger')或外键约束冲突 - 修复代码后,用
php spark migrate:rollback -n 1回退上一次(仅限已成功执行的迁移);若第一次就失败,直接删掉刚生成的迁移文件即可 - 线上环境严禁
php spark migrate:fresh—— 它会删库重建,没有确认提示,CI4 不做任何保护


















