Laravel通过SQL文件进行种子填充

4

我正在尝试从一个.sql文件中读取数据,以便在seeder中填充3-4个表格的一些数据。DatabaseSeeder.php文件如下:

public function run() {
    $this->call([
        UsersTableSeeder::class,
        // Bunch of seeders using Eloquent
        SqlSeeder::class
    ]);
}

所有其他的种子执行了,实际上,在SqlSeeder.php中尝试抛出异常时,我能够停止播种。但是,似乎绕过了php artisan migrate:fresh --seed,SqlSeeder.php不会为数据库播种。我总是需要在之后运行php artisan db:seed --class SqlSeeder,以便让它播种数据库。SqlSeeder.php看起来像这样:

public function run() {
    $path = base_path().'/database/seeds/sql/data.sql';
    $sql = file_get_contents($path);
    DB::unprepared($sql);
}

为什么会这样呢?

php artisan migrate:fresh --seed 执行后,检查所有从 SQL 种子生成的表是否为空。 - Andriy Lozynskiy
dd(DB::unprepared($sql)); 的结果是什么? - Jonas Staudenmeir
解决方案:.sql文件被封装到一个事务中。奇怪的是,当调用php artisan migrate:refresh --seed时,事务和DB::unprepared()不兼容,但在调用--class时可以正常工作。 - Alain D'Ettorre
3个回答

1
我通过从我尝试通过DB::unprepared()执行的.sql文件中删除事务来解决了我的问题。有趣的是,当执行php artisan migrate:refresh --seed时,事务完全失败,但如果稍后通过php artisan db:seed --class SqlSeeder单独调用SqlSeeder,则它们有效。现在没有外键约束,并选择InnoDB作为引擎,只是为了确保,但是无论如何,命令都会导致事务失败或成功。我想这完全取决于Illuminate\Database\Seeder::call如何工作并在内部调用seeder类,但我不确定。

0

检查 SQL 文件中种子数据的顺序是否正确。

例如,如果您有外键 category_id 参考到 categories.id,那么当您使用此 SQL 文件时,posts 表将为空且不会出现任何错误:

INSERT INTO posts (title, category_id) VALUES ('test', 1);
INSERT INTO categories (title) VALUES ('category');

你应该先添加分类,然后再添加文章。


我知道关于种子的顺序,实际上我已经注意到了。在无数次尝试之后,我发现DB::unprepared()和DB::statement()在从DatabaseSeeder.php中调用时不能处理事务,但是如果通过db:seed --class SqlSeeder.php调用,则可以正常工作,并且支持事务。不知道为什么,但是通过将INSERT INTO语句从事务中删除,它可以正常工作! - Alain D'Ettorre

0
在 Laravel 5 中,您只需要在主种子文件中执行以下操作:

\DB::unprepared(\File::get(base_path('path/to/your/sql/file.sql')));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接