reedware/laravel-seeders

增加从种子数据生成和播种的能力。

v1.0.1 2023-06-26 22:35 UTC

This package is auto-updated.

Last update: 2024-08-27 01:24:29 UTC


README

此包增加了从种子数据生成和播种的能力。

Laravel Version Automated Tests Coding Standards Static Analysis Latest Stable Version

介绍

Laravel中的种子非常适合播种假数据,但这不是它们的唯一用途。种子也常用于播种用于术语表类型表格(例如,可枚举的、下拉选项等)或由开发者管理的表格(例如,角色、权限等)的样板应用数据。然而,当播种样板数据时,随着时间的推移可能会出现一些复杂问题。此包旨在提供播种应用数据,并解决以下伴随的复杂问题

  • 您想播种初始数据集,并让应用程序管理其余部分
  • 您想播种初始数据集,偶尔的新条目,并让应用程序管理其余部分
  • 您想让种子器对表有完全控制
  • 您想通过播种管理表,除了少数列外

安装

Composer

可以使用Composer安装此包

composer require reedware/laravel-seeders

服务提供者

此包使用自动发现来注册其服务提供者。如果您选择手动注册提供者,以下是完整的类路径

'providers' => [
    /* ... */
    Reedware\LaravelSeeders\SeederServiceProvider::class
    /* ... */
]

外观

此包使用自动发现来注册其外观。如果您选择手动注册外观,以下是默认绑定

'aliases' => [
    'Seed' => Reedware\LaravelSeeders\Seed::class
]

如果您希望避免使用外观,您可以通过IoC容器获取底层实例

app('db.seed')
// or
app(Reedware\LaravelSeeders\Contracts\Factory::class)

用法

基本示例

要创建第一个种子器,请先创建一个新的种子器,如下所示

<?php

use Reedware\LaravelSeeders\ResourceSeeder;

class PermissionSeeder extends ResourceSeeder
{
    /**
     * The model this resource corresponds to.
     *
     * @var string
     */
    public static $model = \App\Models\Permission::class;

    /**
     * The attributes to match when creating or updating records.
     *
     * @var array
     */
    public static $match = ['name'];

    /**
     * The columns to used order the resources in storage.
     *
     * @var array
     */
    public static $orderBy = ['name' => 'asc'];
}

在此示例中,种子器将从permissions表(从模型派生)生成种子数据,并按name属性对行项目进行排序。当种子器用于从源数据播种时,它将通过name属性匹配现有权限,并相应地进行更新。

允许的操作

默认情况下,资源种子器在播种时将执行以下操作

  • 创建数据库记录,以对应于没有对应数据库记录的种子数据记录
  • 更新具有对应种子数据记录的数据库记录
  • 删除不在种子数据中列出的数据库记录

在此操作模式下,种子数据被视为数据库表的真相来源。

但是,您可以禁用任何操作,如下所示

<?php

use Reedware\LaravelSeeders\ResourceSeeder;

class MySeeder extends ResourceSeeder
{
    /* ... */

    /**
     * Whether or not new records in storage can be inserted into the database.
     *
     * @var boolean
     */
    public static $allowCreating = true;

    /**
     * Whether or not existing records in storage can be updated within the database.
     *
     * @var boolean
     */
    public static $allowUpdating = true;

    /**
     * Whether or not missing records in storage can be deleted from the database.
     *
     * @var boolean
     */
    public static $allowDeleting = true;
}

以下是禁用每个操作的效果

  • 当创建被禁用时,即使种子数据包含不匹配的记录,也不会创建新的数据库记录
  • 当更新被禁用时,现有记录不会更新(如果创建被启用,则仍然可以创建新记录)
  • 当删除被禁用时,即使没有匹配的种子数据记录,也不会删除数据库记录

软删除

当一个播种模型软删除时,种子器的行为将按以下方式改变

  • 软删除的数据库记录仍包含在种子数据生成中
  • "deleted_at"列映射到种子数据中的"trashed"布尔值
  • 在播种时的删除执行为软删除,提供一个播种时的最新时间戳

硬删除

当删除数据库记录时,它可能有外键关联,阻止其删除。通过播种的删除通过模型而不是数据库查询进行,这样您就可以利用Model::deleting(...)事件钩子来删除或解除任何防止其删除的关联。

主键

默认情况下,种子文件不尊重或强制主键。如果您想生成和设置主键,可以像这样启用它们

<?php

use Reedware\LaravelSeeders\ResourceSeeder;

class MySeeder extends ResourceSeeder
{
    /* ... */

    /**
     * Whether or not to omit the primary key.
     *
     * @var boolean
     */
    public static $omitPrimaryKey = false;
}

列映射

如果您想更改生成输出和种子输入,您可以在种子文件中自定义以下方法

<?php

use Reedware\LaravelSeeders\ResourceSeeder;

class MySeeder extends ResourceSeeder
{
    /* ... */

    /**
     * Maps the model attributes to stored attributes.
     *
     * @param  array  $attributes
     *
     * @return array
     */
    public static function mapAttributes(array $attributes)
    {
        $attributes = parent::mapAttributes($attributes);

        $parts = explode(' ', $attributes['full_name']);

        $attributes['first_name'] = array_shift($parts);
        $attributes['last_name'] = $parts;

        return $attributes;
    }

    /**
     * Unmaps stored attributes to model attributes.
     *
     * @param  array  $attributes
     *
     * @return array
     */
    public static function unmapAttributes(array $attributes)
    {
        $attributes = parent::unmapAttributes($attributes);

        $attributes['full_name'] = $attributes['first_name'] . ' ' . $attributes['last_name'];
    }
}

列排除

如果您想防止特定列被种子,可以在资源种子文件中排除它们

<?php

use Reedware\LaravelSeeders\ResourceSeeder;

class MySeeder extends ResourceSeeder
{
    /* ... */

    /**
     * Additional columns to omit when seeding.
     *
     * @var array
     */
    public static $omit = [
        'pretend'
    ];
}

环境特定行为

每个资源种子文件的配置选项已经使用属性显示。如果您想有环境特定行为,您将无法使用属性来实现。幸运的是,每个属性都有一个对应的方法,您可以利用它

<?php

use Reedware\LaravelSeeders\ResourceSeeder;

class MySeeder extends ResourceSeeder
{
    /* ... */

    /**
     * Returns whether or not existing records in storage can be updated within the database.
     *
     * @return boolean
     */
    public static function allowUpdating()
    {
        return app()->environment() !== 'production';
    }
}

命令

要使用本包中的种子文件进行种子,您可以调用传统的 php artisan db:seed --class="MyDatabaseSeeder 命令。

要基于表内容生成种子数据,您可以调用新的 php artisan db:seed:generate --class="MyDatabaseSeeder 命令。

数据存储

您想种子到应用程序中的数据应在源代码中维护,并因此受版本控制。如果对默认配置不满意,种子数据的位置和格式是可定制的。

根路径

默认情况下,此包将种子数据放置在新的 ~/database/seeders/data 目录中。如果您想自定义此位置,可以调用 Seed 门面

<?php

use Illuminate\Support\ServiceProvider;
use Seed;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Seed::setRootPath('where/ever/you/want');
    }
}

模型映射

此包使用您的模型作为源表的参考,因为它检测到了软删除、时间戳使用和其他由您的模型配置的功能。您的模型还用于命名种子数据文件,通过将基于模型的名称转换为复数蛇形(例如,“MyModel”变为“my-models.csv”)。

如果您想覆盖特定模型,可以调用 Seed 门面

Seed::filename(MyModel::class, 'my-filename.csv');

或者,如果您想自定义默认约定,您可以重新定义它

Seed::guessFilenamesUsing(function($class) {
    return $class . '.csv';
});

文件格式

此包使用 csv 文件作为外部存储,但您可能更喜欢其他格式。您可以覆盖文件读取器和写入器以使用您首选的格式

自定义读取器

<?php

use Reedware\LaravelSeeders\Contracts\Reader;

class MyReader implements Reader
{
    //
}

Seed::readUsing(function($filename) {
    return new MyReader($filename);
});

自定义写入器

<?php

use Reedware\LaravelSeeders\Contracts\Writer;

class MyWriter implements Writer
{
    //
}

Seed::writeUsing(function($filename) {
    return new MyWriter($filename);
});