Laravel 数据库迁移和填充实战:从建表到批量生成中文测试数据

陆遥
陆遥
发布时间:2026-08-25| 9人浏览过
原创

前言

团队协作开发时,最容易出问题的往往不是业务代码,而是每个人本地那份“不太一样”的数据库结构。Laravel 的迁移和数据填充,正好解决了“表怎么统一创建”“测试数据怎么快速补齐”这两件麻烦事。下面就按实际使用顺序,把 Laravel 5.5 中从建表、跑迁移到批量生成中文假数据的流程完整过一遍,并把文中遇到的报错处理一并保留下来,方便你判断该怎么落地。

团队协作开发时,最容易出问题的往往不是业务代码,而是每个人本地那份“不太一样”的数据库结构。Laravel 的迁移和数据填充,正好解决了“表怎么统一创建”“测试数据怎么快速补齐”这两件麻烦事。下面就按实际使用顺序,把 Laravel 5.5 中从建表、跑迁移到批量生成中文假数据的流程完整过一遍,并把文中遇到的报错处理一并保留下来,方便你判断该怎么落地。

为什么要用迁移和填充

多人协作时,如果还靠手动执行 SQL、手动给同事补字段,数据库结构很容易出现偏差。迁移的作用,就是把数据表结构也纳入项目代码中管理:谁新增了字段、谁改了表结构,都通过迁移文件记录下来。

在线上部署时,这套方式同样省事。你不需要再手动导入数据库、手工改字段,直接运行迁移命令,就能让目标环境按项目约定创建或更新表结构。

而数据填充解决的是另一类问题:测试、联调、列表分页、搜索筛选这些场景,经常需要大量样例数据。与其一条条手造,不如交给 Seeder 和 Factory 一次性批量生成。

本文基于 Laravel 5.5,其他版本整体思路大同小异。

先把 students 表迁移出来

创建迁移文件

前提是已经配置好了数据库连接信息。先执行下面的 Artisan 命令:

学生表迁移与执行流程专栏配图
迁移如何接管表结构把 students 表结构写进迁移文件后,再通过 migrate 统一执行。
php artisan make:migration create_students_table

命令执行后,会在 database/migrations/ 目录生成一个类似 2017_10_28_035802_create_students_table.php 的文件。接下来就在这个迁移文件里定义 students 表结构。

<?php

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

class CreateStudentsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        // students为表名称
        Schema::create('students', function (Blueprint $table) {
            // 存储引擎
            $table->engine = 'InnoDB';
            // id自增
            $table->increments('id');
            // 学生名称
            $table->string('name');
            // 性别
            $table->string('sex');
            // 邮箱
            $table->string('email');
            // 喜爱的颜色
            $table->string('favorite_color');
            // 手机号
            $table->string('phone');
            // 地址
            $table->string('addr');
            // 自动维护时间戳
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('students');
    }
}

这里的重点并不复杂:up() 负责创建表,down() 负责回滚时删除表。这样一来,数据结构本身也能跟着项目一起管理,而不是散落在某个人的本地 SQL 文件里。

如果需要更多字段类型或索引定义方式,可以继续查 Laravel 官方手册扩展用法。

运行迁移

表结构写好后,直接运行:

Seeder、Factory 与 Faker 中文填充关系图
中文测试数据是怎么批量生成的Seeder 负责调用入口,Factory 定义字段规则,Faker 切到 zh_CN 后。
php artisan migrate

这条命令会执行 database/migrations/ 目录下的所有迁移文件。同时 Laravel 会自动创建一张 migrations 表,用来记录哪些迁移已经执行过,避免重复运行。

正常情况下,执行完成后,数据库里就会自动出现 students 表。

遇到 1071 错误怎么处理

如果迁移时出现下面这类错误:

[IlluminateDatabaseQueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))

[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes

原因通常不是你刚写的 students 表本身,而是 database/migrations/ 目录里 Laravel 自带的用户表、密码重置表迁移文件也会一起执行。在当前环境下,索引长度和字符集配置不兼容,就可能报这个错。

原文给出的处理方式,是修改 config/database.php 里 MySQL 配置的字符集为 utf8:

'charset'     => 'utf8',
'collation'   => 'utf8_unicode_ci',

改完后重新执行迁移即可。原文中提到的原因分析链接如下,保留供继续排查时使用:

https://segmentfault.com/a/1190000008416200

用 Seeder 和 Factory 批量造数据

先创建学生模型

要为 students 表批量生成数据,先在 app 目录下创建 Student.php 模型:

<?php
namespace App;

use IlluminateDatabaseEloquentModel;

/**
 * 学生模型
 */
class Student extends Model
{

}

模型本身很简单,主要是给后面的 Factory 和 Seeder 调用提供入口。

创建 Seeder 文件

接着生成一个学生表填充文件:

php artisan make:seed StudentsTableSeeder

这条命令会在 database/seeds/ 目录下生成 StudentsTableSeeder.php,内容可以改成这样:

<?php

use IlluminateDatabaseSeeder;

class StudentsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // 调用模型工厂 生成10000条数据
        factory(AppStudent::class, 10000)->create();
    }
}

这里的核心动作是:通过模型工厂一次性创建 10000 条数据。数量可以按你的测试需求调整,但原文这里保留的是 10000。

在 DatabaseSeeder 中注册

Seeder 文件生成后,还需要在 database/seeds/DatabaseSeeder.php 里显式调用它:

<?php

use IlluminateDatabaseSeeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        // 调用学生表填充文件
        $this->call(StudentsTableSeeder::class);
    }
}

这一步的意义是把入口统一交给 DatabaseSeeder 管理。后面执行 php artisan db:seed 时,Laravel 就会从这里开始往下调用。

创建模型工厂并定义数据格式

接下来创建工厂文件:

php artisan make:factory StudentsFactory -m Student

命令会在 database/factories/ 目录生成 StudentsFactory.php。然后在其中定义要填充的数据格式:

<?php

use FakerGenerator as Faker;

/* @var IlluminateDatabaseEloquentFactory $factory */

$factory->define(AppStudent::class, function (Faker $faker) {
    $sex = rand(1, 1000);
    return [
        'name'           => $faker->name,
        'sex'            => $sex % 2 == 0 ? '男' : '女',
        'email'          => $faker->unique()->safeEmail,
        'favorite_color' => $faker->safeColorName,
        'phone'          => $faker->phoneNumber,
        'addr'           => $faker->address,
    ];
});

这段定义里,name、email、phone、addr 都交给 Faker 自动生成;sex 则通过随机数的奇偶来决定是“男”还是“女”。

如果你还想扩展更多字段格式,原文建议继续查阅:

vendor/fzaninotto/faker/src/Faker/Generator.php

让 Faker 生成中文测试数据

如果不做额外处理,Faker 默认生成的内容未必符合中文场景。要让名字、地址等字段尽量贴近中文环境,可以在 app/Providers/AppServiceProvider.php 的 boot() 中添加下面这段:

    public function boot()
    {
        // 填充中文数据
        $this->app->singleton(FakerGenerator::class, function () {
            return FakerFactory::create('zh_CN');
        });
    }

这里的关键就是 FakerFactory::create('zh_CN')。配置完成后,Factory 在生成姓名、地址等字段时,就会尽量返回中文数据,而不是默认英文样式。

对于需要演示后台列表、搜索、中文排序、表单校验的项目来说,这一步很实用,因为它让测试数据更接近真实使用环境。

执行填充并检查结果

先刷新自动加载

开始填充前,原文建议先执行一次:

composer dump-autoload

这样可以重新加载你在 database/seeds/ 目录中新建的填充类,避免出现下面这个错误:

[ReflectionException]
Class StudentsTableSeeder does not exist

运行填充命令

确认没问题后,再执行真正的填充命令:

php artisan db:seed

因为这里一次要写入 10000 条数据,所以耗时可能会稍长一些。执行过程中,你甚至可以刷新数据库,看到记录一条条增加。

最终结果是什么样

如果前面的步骤都没有报错,那么 students 表里就应该已经有数据了。原文给出的结果示例如下,可以看到姓名、性别、邮箱、颜色、手机号、地址以及时间戳都已经被批量生成:

id | name | sex | email | favorite_color | phone | addr | created_at |updated_at
---|------|------|------|------|------|------|------|------|------|---
10000   |谈英 |男  |cum_et@example.com |白色 |17642207316    |贵阳海陵区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9999    |汤淑珍    |男  |qlaudantium@example.net    |黑色 |18239453935    |南宁友好区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9998    |贾春梅    |男  |ea35@example.com   |粟色 |17103645128    |长沙萧山区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9997    |季志明    |男  |cdeleniti@example.com  |灰色 |17002359608    |天津花溪区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9996    |成燕 |男  |aspernatur.aut@example.com |黄色 |17181193397    |贵阳锡山区  2017-10-28 05:19:|10    |2017-10-28 05:19:10
9995    |米博 |男  |reprehenderit_autem@example.com    |紫  |17187328893    |广州东丽区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9994    |兰淑兰    |女  |et_ea@example.com  |绿色 |18592254358    |兰州经济开发新区   |2017-10-28 05:19:10    |2017-10-28 05:19:10
9993    |乐瑶 |女  |vel.vitae@example.org  |藏青 |15891490007    |香港龙潭区  2017-10-28 05:19:|10    |2017-10-28 05:19:10
9992    |叶志新    |女  |lcumque@example.net    |藏青 |15564391466    |北京高明区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9991    |胥杨 |男  |voluptatem00@example.com   |黄色 |17097722096    |郑州新城区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9990    |凌敏 |女  |magni22@example.org    |鲜绿色    |13021578051    |杭州涪城区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9989    |席建 |女  |fugiat_accusantium@example.net |紫  |18070573726    |南昌海陵区  |2017-10-28 05:19:10    |2017-10-28 05:19:10
9988    |聂新华    |女  |debitis_sapiente@example.com   |水色 |17004061646    |成都南长区  |2017-10-28 05:19:10    |2017-10-28 05:19:10

到这里,迁移负责“把表建出来”,Seeder、Factory 和 Faker 负责“把数据补进去”,一套完整流程就跑通了。对于团队协作、初始化环境、联调测试和后台开发,这比手工建表和手工造数据稳定得多,也更容易复用。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。