crockett/csv-seeder

使用 CSV 文件进行数据库播种

v1.1.1 2016-02-11 08:41 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:58:26 UTC


README

本包旨在最大限度地减少导入基于 CSV 的数据所花费的时间和麻烦。通过对您的平均 CSV 文件进行一些假设,大多数用户无需任何配置即可开始播种。对于那些需要配置的用户,可用的配置选项提供了对您的 CSV 以及数据如何插入数据库的充分控制。

概述

主要特性

  • 自动将 CSV 标题映射到您的数据库表中的列。
  • 别名允许您在插入之前轻松调整 CSV 列的名称。
  • 可以使用插入回调在插入之前直接操作 CSV 数据。
  • ORM 支持 - 当使用模型时,将应用如 $guarded 和 $fillable 等常见属性到 CSV。

安装

在您的 composer.json 中要求此包并运行 composer update

"crockett/csv-seeder": "1.1.*"

或者直接要求它 composer require crockett/csv-seeder

设置

以下是一个典型的单个 CSV 播种设置示例

use Crockett\CsvSeeder\CsvSeeder;

class UsersTableSeeder extends CsvSeeder {

    public function __construct()
    {
        $this->filename = base_path('path/to/csv/users.csv');
        $this->table = 'users';
    }

    public function run()
    {
        // runs the seeder - alternatively, you could call $this->runSeeder(); for the same result
        parent::run();
    }
}

如果您想在同一个播种器中播种多个 CSV,可以这样做

use Crockett\CsvSeeder\CsvSeeder;

class UsersTableSeeder extends CsvSeeder {

    public function run()
    {
        // seed the users table
        $this->filename = base_path('path/to/csv/users.csv');
        $this->table = 'users';
        parent::run();

        // seed the posts table
        $this->filename = base_path('path/to/csv/posts.csv');
        $this->table = 'posts';
        parent::run();
    }
}

正如您所想象的,这可能会很快变得混乱。相反,您可以使用辅助方法 seedFromCSV(),这仅是一种更干净地定义参数并一次性运行播种器的方法

use Crockett\CsvSeeder\CsvSeeder;

class UsersTableSeeder extends CsvSeeder {

    public function run()
    {
        // seed the users table
        $this->seedFromCSV(base_path('path/to/users.csv'), 'users');

        // seed the posts table
        $this->seedFromCSV(base_path('path/to/posts.csv'), 'posts');
    }
}

使用示例

给定以下 CSV 和数据库表

// users.csv
first_name,last_name,birth_date,password,favorite_color
Joe,Bar,2000-02-10,joePassword,red
Jim,Foo,1990-02-10,jimPassword,blue
Foo,Bar,1980-02-10,fooPassword,green

// users DB table
id, first_name, last_name, birth_date, password, favorite_color

您可以不进行进一步设置即可运行播种器

$this->seedFromCSV(base_path('path/to/users.csv'), 'users');

您甚至可以进一步省略表名,因为 CSV 文件名与表名相同。 CsvSeeder 将自动尝试解析未定义的表名和列名。如果您的 CSV 没有标题行,您需要手动定义一个 $mapping,如下一节所述。

不匹配的列

除非您完全控制您的 CSV,否则标题不会始终与您的 DB 列匹配。例如

// users.csv
first_name, last_name, birth_date, password, favorite_color

// users DB table
id, first_name, last_name, age, password

在这种情况下,您可以定义 $aliasesbirth_date 列重命名为 age 在插入之前

$this->aliases = [
    'birth_date' => 'age'
];

$this->seedFromCSV(base_path('path/to/users.csv'), 'users');

或者,您可以手动为您的 CSV 定义一个 $mapping。映射允许您明确选择并重命名 CSV 列。例如

// users.csv
first_name, last_name, birth_date, password, favorite_color

// users DB table
id, first_name, last_name, color, password

// users seeder
$this->mapping = [
    0 => 'first_name',
    1 => 'last_name',
    3 => 'password',
    4 => 'color', // renamed from favorite_color
];

$this->seedFromCSV(base_path('path/to/users.csv'), 'users');

当您定义一个 $mapping 时,CSV 的标题行 不是 必需的。在其他所有情况下,CsvSeeder 将假定您的标题行是 $offset_rows 之后的第一个行。

插入回调

在某些情况下,您需要在将其插入数据库之前直接操作 CSV 数据。使用 $insert_callback,这再简单不过了!每次从 CSV 读取 $chunk 行时,都会将其传递给默认的 $insert_callback。您需要做的就是定义自己的回调来覆盖它。

在这里,我们将遍历块中的单个行并使用 Model::create() 插入它们

$this->insert_callback = function ($chunk) {
    foreach($chunk as $row) {
        \App\User::create($row->toArray());
    }
};

$this->seedFromCSV(base_path('path/to/users.csv'), 'users');

请注意,$chunk$row\Illuminate\Support\Collection 的实例,因此您可以轻松地操作和过滤行和列

$this->insert_callback = function ($chunk) {
    foreach($chunk as $row) {
        $user_data = $row->only('first_name', 'last_name', 'password')->toArray();
        \App\User::create($user_data);
    }
};

$this->seedFromCSV(base_path('path/to/users.csv'), 'users');

配置

  • table (字符串) 要插入的数据库表。
  • model (字符串) 您可以传递 ORM 模型名称而不是表名。
  • model_guard (布尔值 true) - 在使用模型解析表列时尊重模型属性如 $fillable 和 $guarded。
  • filename (字符串) CSV 文件的路径。
  • delimiter (字符串 ,) CSV 字段分隔符。
  • offset_rows (整数 0) 跳过 CSV 开头多少行。
  • skip_header_row (布尔值 true) 自动跳过第一行,如果确定它是标题行。将 offset_rows 设置为大于 0 会绕过此功能。
  • mapping (数组) 关联数组,格式为 csvColumnIndex >=> csvColumnName。详细信息请参阅示例。如果未指定,CSV 文件中偏移后的第一行将用作映射。
  • aliases (数组) 关联数组,格式为 csvColumnName >=> aliasColumnName。详细信息请参阅示例。允许灵活的 CSV 列名称。
  • hashable (字符串|数组 'password') 使用 bcrypt 对指定的字段进行哈希处理。如果您正在导入用户且需要他们的密码哈希,则非常有用。注意:这非常慢,大 CSV 文件将需要较长时间导入。
  • insert_chunk_size (整数 50) 在读取 CSV 时,每 insert_chunk_size 行将触发一个插入回调。
  • insert_callback (可调用函数) - 用您自己的回调覆盖默认的插入回调。回调必须接受一个包含行 ($chunk) 的 Collection
  • console_logs (布尔值 true) - 在控制台显示消息。(性能影响可以忽略不计)
  • write_logs (布尔值 false) - 将消息写入日志。(对于大型 CSV 文件不建议开启)
  • disable_query_log (布尔值 true) - 禁用查询日志。(对于大型 CSV 文件建议开启)
  • log_prefix (字符串) - 自定义日志消息

更多示例

使用管道分隔的值的 CSV

public function __construct()
{
    $this->table = 'users';
    $this->filename = base_path('database/seeds/csvs/your_csv.csv');
    $this->delimiter = '|';
}

指定要导入的 CSV 列

public function __construct()
{
    $this->table = 'users';
    $this->filename = base_path('database/seeds/csvs/your_csv.csv');
    $this->mapping = [
        0 => 'first_name',
        1 => 'last_name',
        5 => 'age',
    ];
}

使用模型而不是表

public function __construct()
{
    $this->model = \App\User::class;
    $this->filename = base_path('database/seeds/csvs/your_csv.csv');
    // optionally, disable the $model_guard to ignore your model's guarded/fillable attributes
    $this->model_guard = false;
}

跳过 CSV 的第一行(注意:如果偏移后的第一行不是标题行,必须定义映射)

public function __construct()
{
    $this->table = 'users';
    $this->filename = base_path('database/seeds/csvs/your_csv.csv');
    $this->offset_rows = 1;
    $this->mapping = [
        0 => 'first_name',
        1 => 'last_name',
        2 => 'password',
    ];
}

别名 CSV 列

public function __construct()
{
    $this->table = 'users';
    $this->filename = base_path('database/seeds/csvs/your_csv.csv');
    $this->aliases = [
        'age' => 'date_of_birth',
    ];
}

别名在 $mapping 中定义的 CSV 列

public function __construct()
{
    $this->table = 'users';
    $this->filename = base_path('database/seeds/csvs/your_csv.csv');
    $this->mapping = [
        0 => 'first_name',
        1 => 'last_name',
        5 => 'birth_date', // in the CSV file, this column is named 'age'
    ];
    $this->aliases = [
        'birth_date' => 'date_of_birth',
    ];
}

查看 Crockett\CsvSeeder\CsvSeeder 的源代码以获取有关可用方法的更完整信息。

许可

CsvSeeder 是开源软件,许可协议为 MIT 许可协议