【问题标题】:Laravel seeding via SQL fileLaravel 通过 SQL 文件播种
【发布时间】:2018-09-05 00:52:06
【问题描述】:

我正在尝试从播种机中的 .sql 文件中读取数据,以用一些数据填充 3-4 个表,DatabaseSeeder.php 看起来像这样

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

所有其他播种器都会执行,实际上,当尝试在 SqlSeeder.php 中引发异常时,我能够停止播种。但是,SqlSeeder.php 不会通过php artisan migrate:fresh --seed 为数据库播种,似乎被绕过了。我总是需要在之后运行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种子的表是否为空
  • dd(DB::unprepared($sql)); 的结果是什么?
  • 解决方案:将.sql文件封装到事务中。奇怪的是,事务和 DB::unprepared() 在调用 php artisan migrate:refresh --seed 时无法相处,但在调用 --class 时有效

标签: php sql laravel seeding


【解决方案1】:

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

例如,如果您有外键 category_id,当您使用此 sql 文件时,对 categories.id posts 表的引用将为空且没有任何错误:

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

您应该先播种类别,然后才能发布。

【讨论】:

  • 我知道播种顺序,事实上我已经处理好了。经过无数次尝试后,我发现 DB::unprepared() 和 DB::statement() 在从 DatabaseSeeder.php 中调用时无法忍受 transactions,但在使用事务时工作得很好, 如果通过 db:seed --class SqlSeeder.php 调用。不知道为什么,但它通过从事务中删除 INSERT INTO 语句来工作!
【解决方案2】:

我通过从我试图通过DB::unprepared() 执行的 .sql 文件中删除事务解决了我自己的问题。奇怪的是,事务在执行php artisan migrate:refresh --seed 时完全失败,但如果我稍后通过php artisan db:seed --class SqlSeeder 单独调用 SqlSeeder,它们就会工作。目前没有外键约束,并且选择 InnoDB 作为引擎,只是为了确定,但事务仍然失败并根据命令工作。

我想这完全取决于Illuminate\Database\Seeder::call 如何在内部工作和调用播种器类,但我不确定。

【讨论】:

    【解决方案3】:

    对于 Laravel 5,您在主种子文件中要做的就是:

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

    【讨论】:

      猜你喜欢
      • 2014-11-12
      • 2017-04-27
      • 2013-12-01
      • 2018-09-14
      • 2017-09-11
      • 2014-09-05
      • 2015-04-13
      • 2017-06-12
      相关资源
      最近更新 更多