【问题标题】:How do I change a column type with Laravel schema builder?如何使用 Laravel 模式构建器更改列类型?
【发布时间】:2014-03-30 09:40:38
【问题描述】:

我需要将两个字段从整数更改为外键。我如何构建我的迁移来做到这一点?

Schema::create('messages', function($table)
{
    $table->increments('id');
    $table->integer('sender');
    $table->integer('recipient');
    $table->string('title');
    $table->longtext('body');
    $table->timestamps();
    $table->softDeletes();
    $table->integer('regarding');
});

我会将sender 更改为sender_id,将recipient 更改为recipient_id,将regarding 更改为regarding_id

【问题讨论】:

    标签: database laravel-4


    【解决方案1】:

    您可以使用 change() 函数更改列名。这里我提到了一个模式表作为示例

         Schema::table('person', function (Blueprint $table) {
            $table->increments('id');
            $table->text('name')->nullable()->change();
            $table->integer('number')->nullable()->change();
            $table->integer('billing_day')->nullable()->change();
            $table->timestamps()->nullable()->change();
        });
    

    【讨论】:

      【解决方案2】:

      在 Laravel 5 中,您可以使用如下所示的闭包。这应该以与数据库无关的方式进行,因此无需使用 if 语句检查数据库类型。

      (请注意,您可能需要 composer 要求教义/dbal 来执行此操作。)

      public function up() {
          Schema::table('plans', function($t) {
              $t->renameColumn('duration_change_type', 'duration');
          });
      }
      
      public function down() {
          Schema::table('plans', function($t) {
              $t->renameColumn('duration', 'duration_change_type');
          });
      }
      

      【讨论】:

        【解决方案3】:

        我会删除它,然后将其重新添加为不同的类型。

        【讨论】:

          【解决方案4】:

          如果要更改列类型或修改长度等,只需调用change()方法

          Schema::table('users', function ($table) {
              $table->string('id')->change();
          });
          

          并重命名列

          Schema::table('users', function ($table) {
              $table->renameColumn('from', 'to');
          });
          

          【讨论】:

          • @JoanPicornell 乐于提供帮助 :)
          • 有效。只要确保你首先运行composer require doctrine/dbal,按照Laravel docs
          • 卡在将类型字符串更改为整数
          • @AminShojaei 你是在链尾调用 change 方法吗?
          【解决方案5】:

          别想太多,我用的是下面的代码。这里我把数据类型从varchar改成text。

          public function up(){
              DB::statement('ALTER TABLE items MODIFY COLUMN item_description TEXT');
              DB::statement('ALTER TABLE items MODIFY COLUMN delivery_description TEXT');
          }
          
          public function down(){
              DB::statement('ALTER TABLE items MODIFY COLUMN item_description VARCHAR(255)');
              DB::statement('ALTER TABLE items MODIFY COLUMN delivery_description VARCHAR(255)');
          } 
          

          【讨论】:

          • 这不适用于 Postgres,您必须使用它: DB::statement('ALTER TABLE items ALTER COLUMN item_description TYPE VARCHAR(20)');
          • 这是最好的答案。达到 ORM 所能达到的极限是很常见的。您需要知道原始查询何时是更好的选择。
          • 不确定它当时是否不存在,但现在这是非常糟糕的做法。应该使用 Chaudhry Waqas 回答中看到的 ->change() 方法。
          【解决方案6】:

          我刚刚遇到同样的问题,最快的解决方案是简单地更改数据库上的列结构,然后更改原始迁移以反映对数据库所做的更改。

          这样,如果迁移被回滚然后再次向上,则将创建正确的字段。只要您确保准确地更改迁移,我看不出有任何不利之处。

          【讨论】:

          • 如果只部署到一台服务器也可以,但是如果部署到10台服务器,你会去每台单独更改列吗?
          • 不好的做法。你正在失去迁移的目的。考虑一下其他开发人员,他们的本地数据库,他们不知道更改,您现在必须询问他们每个人。
          【解决方案7】:

          我遇到了一个类似的问题,需要将列类型从字符串更改为整数。我使用两个单独的迁移(每个迁移都有一个 RAW sql 语句)来解决这个问题。

          此外,这适用于 Postgres 和 MySQL,因为我们正处于传输过程中。

          第一次迁移:

          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::table('plans', function(Blueprint $table)
              {
                  //
                  $table->mediumInteger('duration_change_type')->default(0)->after('duration');
              });
          
              if (Config::get('database')['default'] === 'mysql'){
                  // Mysql 
                  DB::statement('update plans set duration_change_type=duration');
          
              } else if (Config::get('database')['default'] === 'pgsql'){
                  // PostgreSQL
                  DB::statement('update plans set duration_change_type=duration::integer');
              }
          }
          
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::table('plans', function(Blueprint $table)
              {
                  //
                  $table->dropColumn('duration_change_type');
              });
          }
          

          第二次迁移:

          /**
           * Run the migrations.
           *
           * @return void
           */
          public function up()
          {
              Schema::table('plans', function(Blueprint $table)
              {
                  //
                  $table->dropColumn('duration');
                  $table->renameColumn('duration_change_type', 'duration');
              });
          }
          
          /**
           * Reverse the migrations.
           *
           * @return void
           */
          public function down()
          {
              Schema::table('plans', function(Blueprint $table)
              {
                  // Rollback to string
                  $table->string('duration_change_type')->default(0)->after('duration');
              });
              if (Config::get('database')['default'] === 'mysql'){
                  // Mysql 
                  DB::statement('update plans set duration_change_type=duration');
          
              } else if (Config::get('database')['default'] === 'pgsql'){
                  // PostgreSQL
                  DB::statement('update plans set duration_change_type=duration::text');
              }
          }
          

          现在考虑一下,可以将其简化为一次迁移。

          【讨论】:

            【解决方案8】:

            您可以尝试使用$table->renameColumn('from', 'to'); 将列重命名为临时名称,然后使用外键的标准创建行创建新列,最后使用控制器功能将数据从临时列复制到新列。 应该可以,但我没试过,没必要。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-10-02
              • 1970-01-01
              • 1970-01-01
              • 2014-06-30
              • 2021-08-11
              • 2013-12-21
              • 2013-02-17
              相关资源
              最近更新 更多