数据库种子 - 在一个查询中插入多个记录

时间:2014-08-22 11:08:49

标签: php laravel laravel-4 seeding

我有一个Laravel项目,我想将900个城市插入数据库作为数据库播种。

例如我可以这样做:

$state_id = State::whereName('state name')->pluck('id');

$city = new City();
$city->name = 'my city name';
$city->state_id = $state_id;
$city->save();

在我的城市模型中,我将save定义为:

public function save(array $options = array()) {
    $this->url = $this->createUrl($this->name);
    parent::save($options);
}

因此它也为城市创建了网址。

我可以放置900次这样的代码块但是有一个问题 - 它将在单独的查询中运行,因此将这些数据插入数据库需要30秒以上。

我可以这样做:

DB::table('cities')->insert(
    [
        [
            'name' => 'City name',
            'url' => Slug::create('City name'),
            'created_at' => $now,
            'updated_at' => $now,
            'state_id' => $state_id
        ],
        [
            'name' => 'City name 2',
            'url' => Slug::create('City name 2'),
            'created_at' => $now,
            'updated_at' => $now,
            'state_id' => $state_id
        ],
    ]);

这样我就可以在一个SQL查询中插入很多记录但是在我看来它不是很好的解决方案 - 我需要手动设置所有数据库字段,但插入所有数据只需3-4秒进入数据库。

问题是 - 是否有可能创建模型并使用一些魔术方法返回就绪的PHP数组以在多页插入中使用它(我读过Eloquent不能用于在一个查询中插入多个记录)?

我认为更好的代码是这样的:

$state_id = State::whereName('state name')->pluck('id');

$city = new City();
$city->name = 'my city name';
$city->state_id = $state_id;
$city1 = $city->saveFake(); // magic method that returns complete array

$city = new City();
$city->name = 'my city name';
$city->state_id = $state_id;
$city2 = $city->saveFake(); // magic method that returns complete array

DB::table('cities')->insert(
    [
        $city1,
        $city2,
    ]);

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作,而不是saveFake()函数:

$city->attributesToArray()

这将返回必须存储在表中的所有属性。

您可以将这些添加到数组并将其放入插入函数中。

这会导致类似这样的事情:

$state_id = State::whereName('state name')->pluck('id');
$cities = array();

$city = new City();
$city->name = 'my city name';
$city->state_id = $state_id;
$cities[] = $city->attributesToArray();

$city = new City();
$city->name = 'my city name';
$city->state_id = $state_id;
$cities[] = $city->attributesToArray();

DB::table('cities')->insert($cities);

答案 1 :(得分:0)

$cities = [];
$cities[] = new City(...);
$cities[] = new City(...);
$table = with(new City)->getTable();
$data = array_map(function($city) {
    return $city->getAttributes();
}, $cities);
DB::table($table)->insert($data);

getAttributes返回插入数据库的“原始”基础属性。

请记住,这会绕过保存/创建等Eloquent事件。

另请注意,如果$data变大,您可能会遇到内存问题。如果是这种情况,请使用类似array_chunk()的内容进行拆分。

相关问题