Laravel Geçişleriyle Zaman Damgası Sütununun Varsayılan Değerini Geçerli Zaman Damgasına Nasıl Ayarlayabilirim?


168

CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMPLaravel Schema Builder / Migrations kullanarak varsayılan değeri olan bir zaman damgası sütunu yapmak istiyorum . Laravel belgelerinden birkaç kez geçtim ve bunu bir zaman damgası sütunu için nasıl varsayılan hale getirebileceğimi göremiyorum.

timestamps()İşlev varsayılan yapar 0000-00-00 00:00yapar her iki sütun için.

Yanıtlar:


310

Ham bir ifade olduğu için, bir sütun için varsayılan değer olarak DB::raw()ayarlamanız gerekir CURRENT_TIMESTAMP:

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

Bu, her veritabanı sürücüsünde kusursuz çalışır.

Yeni kısayol

Laravel 5.1.25'ten itibaren (bkz. PR 10962 ve taahhüt 15c487fe ) bir sütun için varsayılan değer olarak useCurrent()ayarlamak için yeni sütun değiştirici yöntemini kullanabilirsiniz CURRENT_TIMESTAMP:

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

Soruya geri dönersek, ON UPDATEMySQL'de maddeyi şu şekillerde de kullanabilirsiniz DB::raw():

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

Sorunlar

  • MySQL

    MySQL 5.7 ile başlayarak 0000-00-00 00:00:00geçerli bir tarih olarak kabul edilmez. Laravel 5.2 yükseltme kılavuzunda belgelendiği gibi , veritabanınıza kayıt eklediğinizde tüm zaman damgası sütunlarının geçerli bir varsayılan değer alması gerekir. Sen kullanabilir useCurrent()şimdiki zaman damgaları için zaman damgası sütunları varsayılan sizin göçlerde (laravel 5.1.25 den ve üzeri) kolon değiştirici veya damgaları yapabilir nullable()boş değerler izin vermek.

  • PostgreSQL ve Laravel 4.x

    Laravel 4.x sürümlerinde PostgreSQL sürücüsü, zaman damgası değerlerini saklamak için varsayılan veritabanı hassasiyetini kullanıyordu. CURRENT_TIMESTAMPVarsayılan bir hassasiyete sahip bir sütunda işlevi kullanırken , PostgreSQL daha yüksek hassasiyete sahip bir zaman damgası üretir, böylece kesirli ikinci bir bölüme sahip bir zaman damgası oluşturur - bu SQL kemanına bakın .

    Bu, Karbon'un bir zaman damgasını ayrıştırmada başarısız olmasına neden olacağından, mikrosaniyelerin depolanmasını beklemez. Bu beklenmedik davranışın uygulamanızı bozmasını önlemek için, CURRENT_TIMESTAMPişleve aşağıdaki gibi açıkça sıfır hassasiyet vermelisiniz :

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

    Laravel 5.0'dan bu yana, timestamp()sütunlar varsayılan bir sıfır hassasiyeti kullanacak şekilde değiştirildi ve bu da bundan kaçındı .

    @Andrewhl'e yorumlarda bu konuyu işaret ettiği için teşekkürler .


Benimkinden daha iyi bir öneri. Örneğim yerine DB::statementbunu kullan, çok daha basit.
Marwelln

Bu, testlerinizdeki PARTITION BY ifadeleri için de kullanılabilir mi?
Glenn Plas

2
Kusursuz değil. PostgreSQL için 'CURRENT_TIMESTAMP' şu formatta bir şey döndürür: 2014-08-11 15: 06: 29.692439. Bu, Carbon :: createFromFormat ('Ymd H: i: s', $ zaman damgası) yönteminin başarısız olmasına neden olur (sondaki milisaniye ayrıştırılamaz). Bu, zaman damgalarına erişirken Laravel tarafından kullanılır. PostgreSQL'i düzeltmek için şunu kullanın: DB :: raw ('now () :: timestamp (0)') (başvuru: postgresql.org/docs/8.1/static/… )
andrewhl

@andrewhl Asıl soru konusu olduğu için sadece MySQL için cevap verdim. Ama bunu bizimle paylaştığın için teşekkürler, cevabımı kapsayacak şekilde güncelleyeceğim! :)
Paulo Freitas

55

Hem created_atve updated_atsütunları oluşturmak için :

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

Birden çok sütuna sahip olmak için MySQL sürüm> = 5.6.5'e ihtiyacınız olacak CURRENT_TIMESTAMP


3
Neden sadece kullanmıyorsunuz $table->timestamps()->default(DB::raw('CURRENT_TIMESTAMP'));?
dave

1
@dave Çünkü updated_atilk yaratıldıktan sonra kayıt değiştirildiği zaman değişmez
Erik Berkun-Drevnig

Evet, bu zaman damgalarına () zaten varsayılanlara izin vermez, bu yüzden işe yaramaz. Buna izin vermek için kod verdim, ancak Laravel yöneticileri gerçekten varsayılanı kullandığımız şekilde kullanmak istemiyorlar (5.6.5'ten önceki MySQL sürümlerinin varsayılan olarak zaman damgalarına sahip birden fazla sütuna izin vermediği varsayılarak).
dave

Aslında updated_at Eloquent tarafından yönetilir, bu yüzden bir model otomatik olarak güncellendiğinde ayarlanacağından "güncelleme" bitine hiç gerek yoktur.
dmyers

@dmyers Eğer eloquent kullanıyorsanız, bunu yapabilirsiniz $t->timestamps();ancak bu soruya cevap vermez.
Brian Adams

44

2015-12-02 tarihinde etiketlenmiş Laravel 5.1.26'dan itibaren bir useCurrent()değiştirici eklendi:

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

PR 10962 ( arkasından 15c487fe taahhüdü ) bu ilaveye yol açtı .

İlgilenilen 3602 ve 11518 sayılarını da okumak isteyebilirsiniz .

Temel olarak, MySQL 5.7 (varsayılan yapılandırmayla), varsayılan bir değer tanımlamanızı veya zaman alanları için null değer vermenizi gerektirir.


10

Bu bir gerçek için işe yaramıyor:

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

Zaman damgası seçilmesiyle gelen 'varsayılan 0'ı kaldırmaz ve yalnızca özel varsayılanı ekler. Ama tırnak işaretleri olmadan buna ihtiyacımız var. Bir DB'yi manipüle eden her şey Laravel4'ten gelmiyor. Bu onun amacı. Şu gibi belirli sütunlarda özel varsayılanlar istiyor:

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

Laravel ile mümkün olduğunu sanmıyorum. Bunun mümkün olup olmadığını görmek için bir saattir arıyordum.


Güncelleme: Paulos Freita'nın cevabı mümkün olduğunu gösteriyor, ancak sözdizimi kolay değil.


Harika. Mükemmel şeyler. Yaşasın, bu da bana yardımcı oldu.
Glenn Plas

küçük bir açıklama, bağırmadan önce: bu benim için laravel'de işe yaramıyor, bu cevabın yazıldığı tarihe bir göz atın: 2013. O zamanlar geçerliydi. Aşağı oka dokunmadan önce çok memnun olurum.
Glenn Plas

9

Gelecekteki Google çalışanları için ek olasılık olarak

Kayıt oluşturulduğunda ancak hiçbir zaman değiştirilmediğinde , updated_at sütununda null olması daha yararlı buluyorum . Db boyutunu azaltır (tamam, biraz) ve ilk bakışta verinin hiç değiştirilmediğini görmek mümkündür.

Bu bağlamda kullanıyorum:

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

(Myysl 8 ile Laravel 7'de).


7

Bunun yerine Paulo Freitas önerisini kullanın.


Laravel bunu düzeltene kadar, çalıştırıldıktan sonra standart bir veritabanı sorgusu Schema::createçalıştırabilirsiniz.

    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");

Benim için harikalar yarattı.


Güzel bir numara. Ben her yerde bu kullanmak gibi şema oluşturucu bölümlenmiş tablolar destekliyorum. Ben kod kazma denedim ama bana bu mod nerede açık değil.
Glenn Plas

-2

İşte böyle yapıyorsunuz, kontrol ettim ve Laravel 4.2 üzerinde çalışıyor.

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

Bu yardımcı olur umarım.


-5

Laravel 5'te basitçe:

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

Belgeler: http://laravel.com/docs/5.1/migrations#creating-columns


13
Ancak bu, varsayılanda soruda belirtildiği gibi CURRENT_TIMESTAMP olarak ayarlanmaz.
Josh

Bunu denemek, ancak 5.4 idk neden null verilen, ama denediğimde -> useCurrent (); iyi çalışıyor
Anthony Kal

değil sorusunu yanıtlıyor yapar CURRENT_TIMESTAMPüzerinde created_atsütun ve on UPDATE CURRENT_TIMESTAMPüzerinde updated_atsütunda. Laravel'deki insanlar düzelene kadar, şunu kullanın: $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP')); $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'));
Hamza Rashid
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.