crockett / csv-seeder
使用 CSV 文件进行数据库播种
Requires
- php: >=5.4.0
- laravel/framework: >=5.0.0
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
在这种情况下,您可以定义 $aliases
将 birth_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 许可协议