
在 Laravel 8 中,数据库迁移(Migration)仅负责结构定义;若需在建表后插入默认记录(如模板、配置项等),应将模型创建逻辑置于 Schema::create() 之外,并确保模型支持批量赋值。
在 laravel 8 中,数据库迁移(migration)仅负责结构定义;若需在建表后插入默认记录(如模板、配置项等),应将模型创建逻辑置于 `schema::create()` 之外,并确保模型支持批量赋值。
在 Laravel 迁移中,Schema::create() 回调函数的作用仅限于定义数据库表结构(如字段、索引、约束等)。它不执行任何数据写入操作——即使你在其中实例化了 Eloquent 模型(如 new Template),也不会自动保存到数据库,除非显式调用 save() 或使用 create() 方法。更重要的是,此时表尚未真正创建完成(迁移执行是分阶段的),在 Schema::create() 内部尝试写入数据不仅逻辑错误,还可能导致 SQL 错误或静默失败。
✅ 正确做法:将数据插入逻辑放在 Schema::create() 之后,并在迁移的 up() 方法末尾统一执行。例如:
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
use App\Models\Template; // 确保正确引入模型
use Illuminate\Support\Collection;
return new class extends Migration
{
public function up(Blueprint $table)
{
Schema::create('templates', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->timestamps();
});
// ✅ 表创建完成后,再插入初始数据
Collection::times(3, fn ($i) => Template::create([
'name' => "Template {$i}"
]));
}
public function down(Blueprint $table)
{
Schema::dropIfExists('templates');
}
};? 关键注意事项:
-
模型可填充性(Mass Assignment):Template::create() 要求 'name' 字段已列入模型的 $fillable 数组,否则会抛出 MassAssignmentException。请确认 app/Models/Template.php 中包含:
protected $fillable = ['name'];
- 避免硬编码与重复插入:该迁移仅在首次运行时生效(由 migrations 表追踪)。但若后续需更新初始数据或支持多环境(如测试/生产),建议改用 Seeder 配合 php artisan db:seed,迁移文件应专注结构变更。
- 事务安全:Laravel 迁移默认在事务中执行(MySQL/PostgreSQL 支持),因此表创建与后续 create() 调用具有原子性——任一失败则全部回滚,保障数据一致性。
- 性能提示:若需插入大量初始记录(如 >100 条),建议改用 DB::table()->insert() 批量原生插入,避免 Eloquent 实例开销。
? 总结:迁移 ≠ 数据填充。始终将 Schema 操作与模型操作分离;利用 Collection::times()、foreach 或 DB::table()->insert() 等方式在结构就绪后注入种子数据,并严格校验模型的 $fillable 和数据库约束兼容性。










