我已经有了一个表名
table_one.
现在我想向其中添加另外两列。到目前为止一切正常。但在我的方法中,我想检查表中是否存在列,例如 dropIfExists('table').
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('table_one', function (Blueprint $table) {
$table->string('column_one')->nullable();
$table->string('column_two')->nullable();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('table_one', function (Blueprint $table) {
// in here i want to check column_one and column_two exists or not
$table->dropColumn('column_one');
$table->dropColumn('column_two');
});
}
你需要这样的东西
public function down()
{
if (Schema::hasColumn('users', 'phone'))
{
Schema::table('users', function (Blueprint $table)
{
$table->dropColumn('phone');
});
}
}
您可以创建自己的“dropColumnIfExists()”函数来检查列是否存在,然后删除它:
function myDropColumnIfExists($myTable, $column)
{
if (Schema::hasColumn($myTable, $column)) //check the column
{
Schema::table($myTable, function (Blueprint $table)
{
$table->dropColumn($column); //drop it
});
}
}
并在“down()”函数上使用它,如下所示:
public function down()
{
myDropColumnIfExists('table_one', 'column_two');
myDropColumnIfExists('table_one', 'column_one');
}
要动态检查表格列,您可以尝试如下操作:
public function dropColumnIfExists($table, $column)
{
if (Schema::hasColumn($table, $column)) //check the column
{
Schema::table($table, function (Blueprint $table) use ($column)
{
$table->dropColumn($column); //drop it
});
}
}
如果您确实希望将其放在
Schema::table
闭包中,这是唯一巧妙的方法...您需要向 Blueprint
添加几个方法,或者在每次迁移中使用此样板...它并不漂亮,但是一旦它出现,您就可以根据需要定义任意数量的条件添加和删除,每个仅使用 1 行。
return new class extends Migration {
public function up() {
Schema::table('tblAnimal', function (Blueprint $table) {
$exists = function (string $column) use ($table) {
return (Schema::hasColumn($table->getTable(), $column));
};
$addUnlessExists = function (string $type, string $name, array $parameters = [])
use ($table, $exists) {
return $exists($name) ? null : $table->addColumn($type, $name, $parameters);
};
$dropIfExists = function (string $column) use ($table, $exists) {
return $exists($column) ? $table->dropColumn($column) : null;
};
$dropIfExists('column_name');
$addUnlessExists('integer', 'int_column');
# ...
});
你应该添加一个这样的功能
public function dropColumnIfExists($tbl,$column)
{
if (Schema::hasColumn($tbl, $column)) {
Schema::table($tbl, function (Blueprint $table) use ($column) {
$table->dropColumn($column);
});
}
}
并在 up 或 down 函数中调用它,如下所示(视为 up 函数)
public function up()
{
$tbl = 'table_name';
Schema::table($tableName, function (Blueprint $table) use ($tbl) {
$this->dropColumnIfExists($tbl,'your_colomn_name');
});
}
很棒的讨论!这是一种支持多数据库的可调用方法。
保持干燥和清洁,具有以下特点:
namespace App\Support\Concerns;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
trait HasManyConnections
{
/**
* Runs a migration conditionally if specified columns do not already exist
*
* @param string $connection
*
* @param string $table
* @param mixed $columns
* @param callable $callback
*
* @return void
*/
function runIfColumnsAreNew(string $connection, string $table, $columns, callable $callback) : void
{
$schema = Schema::connection($connection);
/*----------------------------------------------------------------------------
| Create the table and run the migration if the table doesn't exist
----------------------------------------------------------------------------*/
if(!$schema->hasTable($table)){
$schema->create($table, function (Blueprint $table) use ($callback){
$callback($table);
});
return;
}
/*----------------------------------------------------------------------------
| Iterate the provided columns and determine if any exist
----------------------------------------------------------------------------*/
$migratable = true;
Collection::wrap($columns)->each(function($column) use ($schema, $table, &$migratable){
if($migratable){
$migratable = !$schema->hasColumn($table, $column);
}
});
/*----------------------------------------------------------------------------
| Update the table if all columns are new
----------------------------------------------------------------------------*/
if ($migratable) {
$schema->table($table, function (Blueprint $table) use ($callback){
$callback($table);
});
}
}
}
现在我们将其视为标准迁移,将逻辑传递到闭包中。
use App\Support\Concerns\HasManyConnections;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
use HasManyConnections;
/**
* Run the migrations.
*/
public function up(): void
{
$this->runIfColumnsAreNew('accounts_db', 'profiles', 'squad_name', function(Blueprint $table){
$table->string('squad_name')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
//
}
};
希望有帮助!
只需将模式分解为两个调用
public function up()
{
Schema::table('table_one', function (Blueprint $table) {
$table->dropColumn(['column_one', 'column_two']);
});
Schema::table('table_one', function (Blueprint $table) {
$table->string('column_one')->nullable();
$table->string('column_two')->nullable();
});
}