首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel 5迁移:重命名列时出错

问Laravel 5迁移:重命名列时出错
EN

Stack Overflow用户
提问于 2015-05-16 00:24:10
回答 1查看 1.9K关注 0票数 4

我是拉勒维尔的新手,有这样的迁徙:

代码语言:javascript
复制
public function up()
{
    Schema::table('mytable', function(Blueprint $table)
    {
        $table->renameColumn('mycol', 'old_mycol');
        $table->string('mycol', 100);
    });
}

当我运行它时,我会得到错误:

PDOException SQLSTATE42S21:列已经存在: 1060重复列名'mycol‘

最后,我把它分成了两个单独的迁移,这很好,但是我不明白为什么一次做它是一个问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-16 02:14:37

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

代码语言:javascript
复制
/**
 * 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()两次,如下所示:

代码语言:javascript
复制
Schema::table('mytable', function(Blueprint $table)
{
    $table->renameColumn('mycol', 'old_mycol');
});

Schema::table('mytable', function(Blueprint $table)
{
    $table->string('mycol', 100);
});
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30270558

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档