Laravel 마이그레이션을 통해 타임 스탬프 열의 기본값을 현재 타임 스탬프로 설정하려면 어떻게해야합니까?


168

CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPLaravel Schema Builder / Migrations 를 사용 하는 기본값으로 타임 스탬프 열을 만들고 싶습니다 . 라 라벨 문서를 여러 번 살펴 봤는데 어떻게 타임 스탬프 열의 기본값으로 만들 수 있는지 알 수 없습니다.

timestamps()함수는 0000-00-00 00:00두 열을 모두 기본값 으로 설정합니다.

답변:


310

원시 표현식 인 경우 열의 기본값 DB::raw()으로 설정 해야합니다 CURRENT_TIMESTAMP.

$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

이것은 모든 데이터베이스 드라이버에서 완벽하게 작동합니다.

새로운 지름길

Laravel 5.1.25부터 ( PR 10962commit 15c487fe 참조 ) 새로운 useCurrent()열 수정 자 메소드를 사용하여 열의 CURRENT_TIMESTAMP기본값 으로 설정할 수 있습니다 .

$table->timestamp('created_at')->useCurrent();

질문으로 돌아가서 MySQL에서는 다음 ON UPDATE을 통해 절을 사용할 수도 있습니다 DB::raw().

$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));

잡았다

  • MySQL

    MySQL 5.7부터는 0000-00-00 00:00:00더 이상 유효한 날짜로 간주되지 않습니다. 상기 설명 된대로 Laravel 5.2 업그레이드 가이드 , 모든 타임 스탬프 열은 데이터베이스에 기록 삽입 유효한 기본값을 받아야합니다. 당신은 사용할 수 있습니다 useCurrent()현재 타임 스탬프에 타임 스탬프 열을 기본값으로하여 마이그레이션에 (Laravel 5.1.25에서 이상) 열 수정을하거나 타임 스탬프를 만들 수 있습니다 nullable()널 값을 허용 할 수 있습니다.

  • PostgreSQL 및 Laravel 4.x

    Laravel 4.x 버전에서 PostgreSQL 드라이버는 기본 데이터베이스 정밀도를 사용하여 타임 스탬프 값을 저장했습니다. CURRENT_TIMESTAMP기본 정밀도가있는 열 에서 함수를 사용하는 경우 PostgreSQL은 사용 가능한 정밀도가 더 높은 타임 스탬프를 생성하므로 소수 부분으로 타임 스탬프를 생성합니다 ( 이 SQL 바이올린 참조) .

    이로 인해 카본은 마이크로 초가 저장 될 것으로 예상하지 않기 때문에 타임 스탬프를 구문 분석하지 못했습니다. 이 예기치 않은 동작으로 인해 응용 프로그램이 중단되지 않도록하려면 CURRENT_TIMESTAMP다음과 같이 함수에 정밀도를 0 으로 지정해야합니다.

    $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP(0)'));

    Laravel 5.0부터 timestamp()열을 기본 정밀도 0으로 변경하여이를 방지합니다.

    의견 에서이 문제를 지적 한 @andrewhl 에게 감사드립니다 .


내 더 나은 제안. 내 DB::statement예제 대신 이것을 사용하면 훨씬 간단합니다.
Marwelln

테스트에서 PARTITION BY 문에도 사용할 수 있습니까?
Glenn Plas

2
완벽하지 않습니다. PostgreSQL의 경우 'CURRENT_TIMESTAMP'는 2014-08-11 15 : 06 : 29.692439 형식으로 무언가를 반환합니다. 이로 인해 Carbon :: createFromFormat ( 'Ymd H : i : s', $ timestamp) 메소드가 실패합니다 (후행 밀리 초를 구문 분석 할 수 없음). 타임 스탬프에 액세스 할 때 Laravel에서 사용합니다. PostgreSQL을 수정하려면 다음을 사용하십시오. DB :: raw ( 'now () :: timestamp (0)') (참조 : postgresql.org/docs/8.1/static/… )
andrewhl

@andrewhl 실제로 질문 주제이기 때문에 MySQL에 대해서만 대답했습니다. 그러나 이것을 공유해 주셔서 감사합니다. 이에 대한 답변을 업데이트하겠습니다. :)
Paulo Freitas

55

created_atupdated_at열을 모두 만들려면

$t->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$t->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));

여러 열이있는 MySQL 버전> = 5.6.5가 필요합니다. CURRENT_TIMESTAMP


3
왜 사용하지 $table->timestamps()->default(DB::raw('CURRENT_TIMESTAMP'));않습니까?
데이브

1
@dave updated_at레코드가 처음 생성 된 후에 수정 될 때 변경되지 않기 때문에
Erik Berkun-Drevnig

예, 타임 스탬프 ()를 추가하면 기본값을 허용하지 않으므로 전혀 작동하지 않습니다. 나는 그것을 허용하기 위해 코드를 커밋했지만 Laravel 관리자는 사람들이 우리가 사용하는 방식으로 기본값을 사용하는 것을 실제로 원하지 않습니다 (5.6.5 이전의 MySQL 버전은 기본값으로 타임 스탬프가있는 여러 열을 허용하지 않기 때문에).
dave

실제로 updated_at는 Eloquent에 의해 관리되므로 모델이 자동으로 업데이트 될 때 설정되므로 "업데이트"비트가 전혀 필요하지 않습니다.
dmyers

@dmyers 당신이 웅변을 사용하고 있다면 당신은 할 수는 $t->timestamps();있지만 질문에 대답하지 않습니다.
Brian Adams

44

2015-12-02에 태그가 지정된 Laravel 5.1.26부터 useCurrent()수정자가 추가되었습니다.

Schema::table('users', function ($table) {
    $table->timestamp('created')->useCurrent();
});

PR 10962 ( 커밋 15c487fe )가이 추가로 이어졌습니다 .

관심있는 문제 360211518 을 읽을 수도 있습니다 .

기본적으로 MySQL 5.7 (기본 구성)은 기본값 또는 시간 필드에 대해 널 입력 가능을 정의해야합니다.


10

이것은 사실이 아닙니다.

$table->timestamp('created_at')->default('CURRENT_TIMESTAMP');

타임 스탬프 선택과 함께 나타나는 'default 0'을 제거하지 않고 사용자 지정 기본값을 추가합니다. 그러나 우리는 따옴표없이 필요합니다. DB를 조작하는 모든 것이 Laravel4에서 나오는 것은 아닙니다. 이것이 그의 요점입니다. 그는 다음과 같은 특정 열에서 사용자 정의 기본값을 원합니다.

$table->timestamps()->default('CURRENT_TIMESTAMP');

라 라벨에서는 가능하지 않다고 생각합니다. 가능한지 확인하기 위해 한 시간 동안 검색했습니다.


업데이트 : Paulos Freita의 답변에 따르면 가능하지만 구문은 간단하지 않습니다.


큰. 완벽한 물건. 엄지 손가락, 이것은 나에게도 도움이되었습니다.
Glenn Plas

소리 지르기 전에 약간의 발언 : laravel에서는 나에게 도움이되지 않습니다.이 답변이 작성된 날짜를 확인하십시오 : 2013. 당시에는 유효했습니다. 아래쪽 화살표를 누르기 전에 감사하겠습니다.
Glenn Plas

9

미래 Google 직원을위한 추가 가능성

레코드가 작성되었지만 수정되지 않은 경우 updated_at 열에 null 을 추가하는 것이 더 유용하다는 것을 알았 습니다 . DB 크기를 줄이고 (약간 조금만) 데이터를 수정 한 적이없는 첫 순간에 볼 수 있습니다.

이 시점에서 나는 다음을 사용합니다.

$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->default(DB::raw('NULL ON UPDATE CURRENT_TIMESTAMP'))->nullable();

(mysql 8의 Laravel 7에서).


7

대신 Paulo Freitas 제안을 사용하십시오 .


Laravel이이 문제를 해결하기 전까지는 표준 데이터베이스 쿼리를 실행 한 후에 Schema::create실행할 수 있습니다.

    Schema::create("users", function($table){
        $table->increments('id');
        $table->string('email', 255);
        $table->string('given_name', 100);
        $table->string('family_name', 100);
        $table->timestamp('joined');
        $table->enum('gender', ['male', 'female', 'unisex'])->default('unisex');
        $table->string('timezone', 30)->default('UTC');
        $table->text('about');
    });
    DB::statement("ALTER TABLE ".DB::getTablePrefix()."users CHANGE joined joined TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL");

그것은 나를 위해 놀라운 일을했다.


좋은 트릭입니다. 스키마 빌더가 파티션 테이블을 지원하기를 원했습니다. 코드를 파고 들었지만이 부분을 수정 해야하는 것은 분명하지 않습니다.
Glenn Plas

-2

이것은 당신이 그것을하는 방법입니다, 나는 그것을 확인했고 그것은 나의 라 라벨 4.2에서 작동합니다.

$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));

도움이 되었기를 바랍니다.


-5

라 라벨 5에서 ​​간단히 :

$table->timestamps(); //Adds created_at and updated_at columns.

설명서 : http://laravel.com/docs/5.1/migrations#creating-columns


13
그러나 이것은 질문에서 묻는 것처럼 기본값을 CURRENT_TIMESTAMP로 설정하지 않습니다.
Josh

나는 이것을 시도하지만 5.4 idk에 null이 주어진 이유, 그러나 내가 시도 할 때-> useCurrent (); 잘 작동
Anthony Kal

하지의 질문에 대답하지 CURRENT_TIMESTAMPcreated_at칼럼 on UPDATE CURRENT_TIMESTAMPupdated_at열을. : Laravel에서 사람들이 문제를 해결할 때까지이 사용 $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP')); $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));
함자 라시드
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.