我有一个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,
]);
答案 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()
的内容进行拆分。