检查 Laravel 迁移文件中是否存在列

问题描述 投票:0回答:7

我已经有了一个表名

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');
    });
}
php sql laravel
7个回答
164
投票

你需要这样的东西

  public function down()
    {
        if (Schema::hasColumn('users', 'phone'))
        {
            Schema::table('users', function (Blueprint $table)
            {
                $table->dropColumn('phone');
            });
        }
    }

13
投票

您可以创建自己的“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');
}

4
投票

要动态检查表格列,您可以尝试如下操作:

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

}

3
投票

如果您确实希望将其放在

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');
            # ...
        });

1
投票

你应该添加一个这样的功能

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

1
投票

很棒的讨论!这是一种支持多数据库的可调用方法。

保持干燥和清洁,具有以下特点:

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
    {
        //
    }
};

希望有帮助!


-14
投票

只需将模式分解为两个调用

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();
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.