【问题标题】:Split a `dateTime` column into a separate `date` and `time` column in Laravel 5在 Laravel 5 中将 `dateTime` 列拆分为单独的 `date` 和 `time` 列
【发布时间】:2017-06-15 13:09:13
【问题描述】:

我有一个名为“offers”的表,其中有一列名为 start_date 的类型为 dateTime

我想将此列拆分为两个单独的列:

  • start_date 类型为 date
  • start_time 类型为 time

为此,我有以下代码:

<?php

use App\Offer;
use Carbon\Carbon;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class FixOffersTable extends Migration
{
    public function up()
    {
        Schema::table('offers', function(Blueprint $table)
        {
            $table->renameColumn('start_date', 'start_date_time');
            $table->renameColumn('end_date', 'end_date_time');
        });

        Schema::table('offers', function (Blueprint $table)
        {
            $table->date('start_date')->after('start_date_time')->nullable();
            $table->time('start_time')->after('start_date')->nullable();

            foreach (Offer::all() as $offer) {
                /* Cannot use model mutator, as model class can change over time, and may no longer have certain columns
                in the $casts attribute. Therefore using the raw string fetched from the MySQL database. */
                $startDateTime = Carbon::createFromFormat('Y-m-d H:i:s', $offer->getOriginal('start_date_time'));
                $offer->start_date = Carbon::createFromDate($startDateTime->year, $startDateTime->month, $startDateTime->day);
                $offer->start_time = Carbon::createFromTime($startDateTime->hour, $startDateTime->minute, $startDateTime->second);
                $offer->save();
            }
        });
    }
}

但是上面给出了以下错误:

[Doctrine\DBAL\Schema\SchemaException]                        
There is no column with name 'start_date' on table 'offers'. 

但是,将“for 循环”注释掉意味着此错误不再存在,这意味着问题出在某个地方。

也欢迎更好的方法!

【问题讨论】:

  • 您是否尝试过将 foreach 循环从 Schema 闭包中取出?我的猜测是该列尚未创建
  • 是的。同样的错误
  • 您在 foreach 循环中尝试执行的操作更适合控制台命令。我不确定在迁移过程中列创建实际完成的时间点,但错误似乎很明显就是问题所在,所以我将在迁移之外运行它
  • 你为什么要定义同一个函数两次? Schema::table('offers', function (Blueprint $table),相同的逻辑不能只用一个函数实现吗?
  • 不。这是一个奇怪的 Laravel 问题。原因是首先执行创建列,因此重命名代码将导致重复错误

标签: php mysql laravel laravel-5 laravel-migrations


【解决方案1】:

回答了我自己的问题。我收到此错误的原因有两个。

原因 1,我要求一个列在另一列之后,但它还不存在。

原因 2,我正在使用尚未创建的列创建优惠。

应该是这样的:

<?php

use App\Offer;
use App\Schedule;
use Carbon\Carbon;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class FixOffersTable extends Migration
{
    public function up()
    {
        DB::beginTransaction();

        Schema::table('offers', function(Blueprint $table)
        {
            $table->renameColumn('start_date', 'start_date_time');
            $table->renameColumn('end_date', 'end_date_time');
        });

        Schema::table('offers', function (Blueprint $table)
        {
            $table->time('start_time')->after('start_date_time')->nullable();
            $table->date('start_date')->after('start_date_time')->nullable();
        });


        foreach (Offer::all() as $offer) {
           /* Cannot use model mutator, as model class can change over time, and may no longer have certain columns
            in the $casts attribute. Therefore using the raw string fetched from the MySQL database. */
            $startDateTime = Carbon::createFromFormat('Y-m-d H:i:s', $offer->getOriginal('start_date_time'));
            $offer->start_date = Carbon::createFromDate($startDateTime->year, $startDateTime->month, $startDateTime->day);
            $offer->start_time = Carbon::createFromTime($startDateTime->hour, $startDateTime->minute, $startDateTime->second);
            $offer->save();
        }


        DB::commit();
    }
}

【讨论】:

    猜你喜欢
    • 2012-08-13
    • 2014-08-14
    • 2012-09-02
    • 2018-05-17
    • 1970-01-01
    • 2017-11-02
    • 1970-01-01
    • 2020-12-14
    • 2019-11-05
    相关资源
    最近更新 更多