Laravel 8-当数据库并没有表时,用程序运行迁移和种子程序



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

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);
}

或者,有没有替代注入代码的方法?提前谢谢。

我建议您查看composer脚本部分-有很多事件可以用作代码的触发器。例如在composer dumpautoload之后激发的post-autoload-dump事件,其在诸如installupdate之类的最常见调用中激发或由其自身激发。使用composer事件的好处是不需要在每个请求中检查现有的表。

实现这一点最简单的方法是创建自定义的手工命令

php artisan make:command PrepareEmptyDatabase

则在appConsoleCommandsPrepareEmptyDatabase.php

<?php
namespace AppConsoleCommands;
use Exception;
use AppHttpModelsUser;
use IlluminateConsoleCommand;
use IlluminateSupportFacadesSchema;
use IlluminateSupportFacadesArtisan;
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事件联系起来,因此在composer.json

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

现在,无论何时安装/更新composer依赖项,或者只是运行composer dumpatoload应用程序,都将运行您的自定义命令。或者你可以在你的口味上坚持作曲家文档事件中提供的任何内容


关于在npm run dev

之后运行相同的代码我不太确定搜索的地方,猜测是关于webpack事件的,但你的问题标记了laravel,所以我假设你使用的是laravel混合,并且有事件挂钩

快速谷歌搜索表明nodejs可以使用nodejs子进程运行bash脚本

// 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,我真的不明白为什么在前端构建事件中需要它(如果只是为了测试目的,即使这样也有问题)

最新更新