Laravel 8 - 当数据库没有表时以编程方式 运行 迁移和播种器

Laravel 8 - Programmatically run migration and seeder when database has no tables

连接到数据库后,一旦项目检测到数据库没有任何表,我想以编程方式运行 迁移和播种。 我想我应该做的是在某处注入下面的代码,但我不知道我应该编辑哪个文件。

if (!Schema::hasTable('users')) {
    $init_met = ini_get('max_execution_time');
    set_time_limit(300);
    Artisan::call('migrate:fresh');
    Artisan::call('db:seed');
    set_time_limit($init_met);
}

或者,是否有替代方法来代替注入代码? 提前致谢。

我建议您查看作曲家脚本部分 - 有很多 events 可以用作代码的触发器。例如 post-autoload-dump 事件在 composer dumpautoload 之后触发,它在最常见的调用如 installupdate 中触发或单独触发。使用 composer 事件的好处是您不需要在每次请求时检查现有表。

最简单的方法是创建 custom artisan command

php artisan make:command PrepareEmptyDatabase

然后在app\Console\Commands\PrepareEmptyDatabase.php

<?php

namespace App\Console\Commands;

use Exception;
use App\Http\Models\User;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\Artisan;

class PrepareEmptyDatabase extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'db:prepare-empty';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'check for users table and run migrations and seed if has not';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        // don't forget to remove this if database user
        // don't have access to dba tables
        if (Schema::hasTable('users')) {
            return Command::SUCCESS;
        }

        /* 
        // if your user doesn't have permission to access to dba tables
        // you can simply try to do any request to users table
        
        $needActions = false;
        try {
            User::first();
        } catch (Exception $ex) {
            $needActions = true;
        }
        if (!$needActions) {
            return Command::SUCCESS;
        }
        */
        $init_met = ini_get('max_execution_time');
        set_time_limit(300);
        Artisan::call('migrate:fresh');
        Artisan::call('db:seed');
        set_time_limit($init_met);
        return Command::SUCCESS;
    }
}

最后一步是将此命令与作曲家事件联系起来,所以在 composer.json

"scripts": {    
    "post-autoload-dump": [
      "Illuminate\Foundation\ComposerScripts::postAutoloadDump",
      "@php artisan package:discover",
      "@php artisan db:prepare-empty"
    ]
  },

现在任何时候你 install/update composer 依赖项或只是 运行 composer dumpatoload 应用程序都会 运行 你的自定义命令。或者您可以根据自己的口味坚持使用 composer docs 事件中提供的任何内容


关于 运行在 npm run dev
之后使用相同的代码

我不太确定要搜索的地方,猜测它是关于 webpack 事件的,但是你的问题用 laravel 标记所以我假设你正在使用 laravel-mix and there are event hooks

快速谷歌搜索说 nodejs 可以 运行 bash 使用 nodejs child process

的脚本
// webpack.mix.js
const exec = require('child_process')
// or import exec from 'child_process'
mix
  .js('resources/assets/js/app.js', 'public/js')
// other configs
  .after(() => {
    exec.execSync('php artisan db:prepare-empty')
  })

请注意,此代码将 运行 用于任何混合,甚至包括 npm run prod 例如,我实际上不明白为什么在前端构建事件中需要它(如果仅用于测试目的)甚至还有问题)