php - Laravel 5 迁移 : error while renaming columns

标签 php mysql laravel-5

我是 Laravel 的新手并且有这样的迁移:

public function up()
{
    Schema::table('mytable', function(Blueprint $table)
    {
        $table->renameColumn('mycol', 'old_mycol');
        $table->string('mycol', 100);
    });
}

当我运行它时,出现错误:

[PDOException]
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'mycol'

我最终将其拆分为 2 个单独的迁移并且工作正常,但我不明白为什么一次完成它是一个问题。

最佳答案

这是因为在执行迁移时,Laravel 会隐式地将任何添加新列或修改现有列的命令放在命令数组的最开头。以下代码直接取自 Illuminate\Database\Schema\Blueprint 类。

/**
 * Get the raw SQL statements for the blueprint.
 *
 * @param  \Illuminate\Database\Connection  $connection
 * @param  \Illuminate\Database\Schema\Grammars\Grammar  $grammar
 * @return array
 */
public function toSql(Connection $connection, Grammar $grammar)
{
    $this->addImpliedCommands();

    $statements = array();

    // Each type of command has a corresponding compiler function on the schema
    // grammar which is used to build the necessary SQL statements to build
    // the blueprint element, so we'll just call that compilers function.
    foreach ($this->commands as $command)
    {
        $method = 'compile'.ucfirst($command->name);

        if (method_exists($grammar, $method))
        {
            if ( ! is_null($sql = $grammar->$method($this, $command, $connection)))
            {
                $statements = array_merge($statements, (array) $sql);
            }
        }
    }

    return $statements;
}

/**
 * Add the commands that are implied by the blueprint.
 *
 * @return void
 */
protected function addImpliedCommands()
{
    if (count($this->getAddedColumns()) > 0 && ! $this->creating())
    {
        array_unshift($this->commands, $this->createCommand('add'));
    }

    if (count($this->getChangedColumns()) > 0 && ! $this->creating())
    {
        array_unshift($this->commands, $this->createCommand('change'));
    }

    $this->addFluentIndexes();
}

从上面的代码可以看出,在 toSql 方法中,有一个对 addImpliedCommands 的调用,其中可能会将几个命令添加到命令数组的开头的对象。这会导致在重命名命令之前首先执行新的 mycol 列的命令。

要解决这个问题,您不需要真的需要创建两个迁移。在同一迁移中,您可以像这样简单地调用 Schema::table() 两次:

Schema::table('mytable', function(Blueprint $table)
{
    $table->renameColumn('mycol', 'old_mycol');
});

Schema::table('mytable', function(Blueprint $table)
{
    $table->string('mycol', 100);
});

关于php - Laravel 5 迁移 : error while renaming columns,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30270558/

相关文章:

javascript - 拉维尔 5.2 :How to show validation errors when submitting form with ajax?

mysql - 在网站上的 MySQL 中使用 UTC

php - 出现一般错误 : 4004 General SQL Server error:

php - Laravel 查询变量作为字符串

php - laravel 5如何将数据传递到 Controller 到模型

javascript - 使用js绘制饼图

php - 如何从 PHP 中的 UTF8 字符获取 "remove diacritics"?

php - 根据另一个选择显示一个选择的下拉值

python - MySQL 选择产品的所有组件

mysql - 根据一列数据合并MySQL中的2个表