插入数千条记录时在laravel中使用faker

问题描述

我在使用 laravel faker 时遇到一个问题,我正在寻找使用播种机插入数千条记录的教程

这是我的 PostSeeder.PHP

<?PHP

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Post;
use App\Models\User;

class PostSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {            
        Post::factory(10)->create();
    }
}

这里我插入了10个帖子,但我需要测试数千或数百万条记录,所以看了一个教程并修改了播种机

<?PHP

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use App\Models\Post;
use App\Models\User;
use Illuminate\Support\Str;

class PostSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {        
        
        $users= collect(User::all()->modelKeys());
        $data = [];

        for ($i = 0; $i < 100000; $i++) {
            $data[] = [
                'body' => Str::random(50),'image' => 'https://via.placeholder.com/640x480.png/0077dd?text=inventore','user_id' => $users->random(),'created_at' => Now()->toDateTimeString(),'updated_at' => Now()->toDateTimeString(),];
        }

        $chunks = array_chunk($data,10000);

        foreach ($chunks as $chunk) {
            Post::insert($chunk);
        }
        
    }
}

使用这种方法我可以更快地插入数千条记录,但问题是我没有正确插入正文和图像字段

我想用 faker 尝试一些东西,在我的工厂我有这个:

PostFactory.PHP

<?PHP

namespace Database\Factories;

use App\Models\Post;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class PostFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Post::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function deFinition()
    {
        return [
            'body' => $this->faker->text,'image' => $this->faker->imageUrl(),'user_id' => function() {
                return User::factory()->create()->id;
            }
        ];
    }
}

我想在 PostSeeder 中使用像这些这样的伪造方法,但我不能,我该怎么办?谢谢。

编辑:

我试过了:

public function run(Faker $faker)
    {                
        
        $users= collect(User::all()->modelKeys());
        $data = [];

        for ($i = 0; $i < 50000; $i++) {
            $data[] = [
                'content' => $faker->text,'image_path' => $faker->imageUrl(),5000);

        foreach ($chunks as $chunk) {
            Post::insert($chunk);
        }
        
    }

我收到了这条消息: PDOException::("sqlSTATE[HY000]: 一般错误:2006 MysqL 服务器已经消失") 但是当我尝试使用较少的记录时它会起作用,因此,我像这样更改了播种机:

$users= collect(User::all()->modelKeys());
$posts = Post::factory(10)->create();        
$posts = collect($posts->only(['content','image_path']));
...
...
'content' => $posts->random()->content,'image_path' => $posts->random()->image_path
...

这不起作用,它得到了这个错误您请求了 1 个项目,但只有 0 个项目可用。 看起来 $posts->only(['content','image_path']) 工作不正常。所以我尝试了这个:

Post::factory(10)->create();
$tweets = Tweet::select(['content','image_path'])->get();
...
'content' => $posts->random()->content,'image_path' => $posts->random()->image_path
...

它再次处理一些记录,但是当我尝试处理数千条记录时,我再次收到此错误PDOException::("sqlSTATE[HY000]: 一般错误:2006 MysqL 服务器已经消失")

我能做什么?谢谢

解决方法

由于模型工厂在内存中创建对象,因此内存使用量大,不适合大种子。

但是您可以使用 Faker 来生成数据:

use Faker\Generator as Faker;
class PostSeeder extends Seeder
{
    public function run(Faker $faker)
    {
        $users= collect(User::all()->modelKeys());
        $data = [];

        for ($i = 0; $i < 100000; $i++) {
            $data[] = [
                'body' => $faker->text,'image' => $faker->imageUrl(),'user_id' => $users->random(),'created_at' => now()->toDateTimeString(),'updated_at' => now()->toDateTimeString(),];
        }

        $chunks = array_chunk($data,10000);

        foreach ($chunks as $chunk) {
            Post::insert($chunk);
        }
    }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...