255 votes

Comment puis-je définir la valeur par défaut d'une colonne d'horodatage sur l'horodatage actuel avec les migrations Laravel ?

Je voudrais créer une colonne d'horodatage avec une valeur par défaut de CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP en utilisant le Laravel Schema Builder/Migrations. J'ai parcouru plusieurs fois la documentation de Laravel, et je ne vois pas comment je peux faire en sorte que ce soit la valeur par défaut pour une colonne d'horodatage.

El timestamps() rend les valeurs par défaut 0000-00-00 00:00 pour les deux colonnes qu'il fait.

461voto

Paulo Freitas Points 3039

Étant donné qu'il s'agit d'une expression brute, vous devriez utiliser DB::raw() pour fixer CURRENT_TIMESTAMP comme valeur par défaut pour une colonne :

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

Cela fonctionne parfaitement avec tous les pilotes de base de données.

À partir de Laravel 5.1.25 (voir PR 10962 y commit 15c487fe ), vous pouvez désormais utiliser la nouvelle useCurrent() pour obtenir la même valeur par défaut pour une colonne :

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

Pour en revenir à la question, sur MySQL, vous pouvez également utiliser le fichier ON UPDATE clause par DB::raw() :

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

Là encore, à partir de Laravel 8.36.0 (voir PR 36817 ), vous pouvez désormais utiliser la nouvelle useCurrentOnUpdate() ainsi que la méthode de modification de la colonne useCurrent() pour obtenir la même valeur par défaut pour une colonne :

$table->timestamp('updated_at')->useCurrent()->useCurrentOnUpdate();

Gotchas

  • MySQL

    À partir de MySQL 5.7, 0000-00-00 00:00:00 n'est plus considérée comme une date valide. Comme le documente le Guide de mise à niveau de Laravel 5.2 Dans le cas de l'horodatage, toutes les colonnes d'horodatage doivent recevoir une valeur par défaut valide lorsque vous insérez des enregistrements dans votre base de données. Vous pouvez utiliser l'option useCurrent() (à partir de Laravel 5.1.25 et plus) dans vos migrations pour que les colonnes d'horodatage prennent par défaut les horodatages actuels, ou vous pouvez faire en sorte que les horodatages nullable() pour autoriser les valeurs nulles.

  • PostgreSQL et Laravel 4.x

    Dans les versions Laravel 4.x, le pilote PostgreSQL utilisait la précision par défaut de la base de données pour stocker les valeurs d'horodatage. Lorsque l'on utilisait l'option CURRENT_TIMESTAMP sur une colonne avec une précision par défaut, PostgreSQL génère un horodatage avec la plus haute précision disponible, générant ainsi un horodatage avec une seconde partie fractionnaire - voir cette manipulation SQL .

    Cela conduira Carbon à ne pas analyser un timestamp car il ne s'attend pas à ce que des microsecondes soient stockées. Pour éviter que ce comportement inattendu ne perturbe votre application, vous devez explicitement donner une précision de zéro à la variable CURRENT_TIMESTAMP comme ci-dessous :

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

    Depuis Laravel 5.0, timestamp() a été modifié pour utiliser une précision par défaut de zéro, ce qui évite ce problème.

Merci à @andrewhl pour avoir signalé le problème de Laravel 4.x dans les commentaires.

Merci à @ChanakaKarunarathne pour avoir fait ressortir le nouveau useCurrentOnUpdate() raccourci dans les commentaires.

65voto

Brian Adams Points 313

Pour créer les deux created_at y updated_at colonnes :

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

Vous devez disposer d'une version de MySQL >= 5.6.5 pour avoir plusieurs colonnes avec des noms de domaine. CURRENT_TIMESTAMP

58voto

Double Gras Points 2304

À partir de Laravel 5.1.26, étiqueté le 2015-12-02, une useCurrent() a été ajouté :

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

PR 10962 (suivi de commit 15c487fe ) a conduit à cet ajout.

Vous pouvez également lire les questions suivantes 3602 y 11518 qui présentent un intérêt.

Fondamentalement, MySQL 5.7 (avec la configuration par défaut) exige que vous définissiez soit une valeur par défaut, soit une valeur nulle pour les champs de temps.

44voto

ndberg Points 363

Comme possibilité supplémentaire pour les futurs googleurs

Je trouve plus utile d'avoir null dans la colonne updated_at lorsque l'enregistrement a été créé mais n'a jamais été modifié . Cela réduit la taille de la base de données (ok, juste un peu) et il est possible de voir à première vue que les données n'ont jamais été modifiées.

A partir de maintenant, j'utilise :

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

(Dans Laravel 7+8 avec mysql 8).


Edit : Depuis Laravel 8, vous pouvez également utiliser :

$table->timestamp('created_at')->useCurrent();
$table->timestamp('updated_at')->nullable()->useCurrentOnUpdate();

pour obtenir le même résultat.

Merci à @bilogic de l'avoir signalé.

13voto

Glenn Plas Points 685

Cela ne fonctionne pas, c'est un fait :

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

Il ne supprime pas le "0 par défaut" qui semble accompagner la sélection de l'horodatage et ajoute simplement la valeur par défaut personnalisée. Mais nous en avons besoin sans les guillemets. Tout ce qui manipule une base de données ne vient pas de Laravel4. C'est là où il veut en venir. Il veut des valeurs par défaut personnalisées sur certaines colonnes, par exemple :

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

Je ne pense pas que ce soit possible avec Laravel. Cela fait une heure que je cherche à savoir si c'est possible.


Mise à jour : Paulos Freita's réponse montre que c'est possible, mais la syntaxe n'est pas simple.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X