Knex: table.timestamps() doit définir ON UPDATE CURRENT_TIMESTAMP pour updated_ts

Créé le 21 févr. 2017  ·  8Commentaires  ·  Source: knex/knex

Attendu:
Lors de la création de la colonne updated_ts dans table.timestamps() , son DDL doit être :

timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

Réel:
La partie ON UPDATE CURRENT_TIMESTAMP est manquante - la colonne updated_ts n'est jamais mise à jour automatiquement.

La syntaxe que je décris fonctionne pour MySQL, je ne suis pas sûr de sa compatibilité avec les moteurs de base de données.

Commentaire le plus utile

Je pense que timestamps() doit fournir cette fonctionnalité de mise à jour automatique ou que la documentation doit indiquer explicitement que ce n'est pas le cas. J'ai simplement supposé que la fonctionnalité était une raison essentielle pour laquelle la méthode timestamps() existe.

Tous les 8 commentaires

Au moins, avec la syntaxe postgres, ce n'est pas vraiment sympa :

http://stackoverflow.com/questions/1035980/update-timestamp-when-row-is-updated-in-postgresql

Bien que je voudrais avoir .autoUpdate() méthode constructeur pour timestamp colonne, il serait alors trivial pour permettre que de .timestamps() aide aussi.

On dirait que SQLite3 a également des déclencheurs qui pourraient être utilisés pour implémenter cela. Oracle et mssql pourraient également avoir une syntaxe plus agréable pour cela ou au moins cela pourrait être fait avec des déclencheurs.

Ce serait tellement sympa ! actuellement, nous devons dépendre de l'étagère pour mettre à jour nos horodatages, n'est-ce pas ?

Au lieu de vous fier à la bibliothèque, vous pouvez créer les champs datetime manuellement (mysql) :

table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').defaultTo(knex.raw('NULL ON UPDATE CURRENT_TIMESTAMP'))

Ou si vous préférez que updated_at défini par défaut sur l'heure de création :

table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'))

Au lieu de vous fier à la bibliothèque, vous pouvez créer les champs datetime manuellement (mysql) :

table.dateTime('created_at').notNullable().defaultTo(knex.raw('CURRENT_TIMESTAMP'))
table.dateTime('updated_at').defaultTo(knex.raw('NULL ON UPDATE CURRENT_TIMESTAMP'))

L'utilisation du code que vous avez publié pour updated_at avec null par défaut insère toujours l'horodatage actuel pour updated_at.

const UserModel = bookshelf.Model.extend({
  tableName: 'users',
  hasTimestamps: ['createdAt', 'updatedAt'],
});

Ce test échoue :

it('doesntStoreUpdatedAtForCreation', async () => {
    // arrange && act
    const inserted = await new UserModel().save();

    // assert
    const retrievedModel = await UserModel.where({ id: inserted.id }).fetch();
    assert.notExists(retrievedModel.get('updatedAt'));
  });

Éditer:
Peu importe, il semble que la suppression complète de hasTimestamps de la définition du modèle résout ce problème.

Nous mélangeons ici les problèmes de Knex et de Bookshelf, mais @Ice32 si vous ne souhaitez pas utiliser la fonction d'horodatage automatique de Bookshelf, vous devez supprimer hasTimestamps: ['createdAt', 'updatedAt'] de votre définition de modèle. Le code que @codeclown a publié ci-dessus fonctionnera alors comme prévu.

Ma solution :

const Database = use("Database");
/*......*/
table
        .timestamp("created_at")
        .notNullable()
        .defaultTo(Database.raw("CURRENT_TIMESTAMP"));

table
        .timestamp("updated_at")
        .notNullable()
        .defaultTo(
            Database.raw("CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
        );

Je pense que timestamps() doit fournir cette fonctionnalité de mise à jour automatique ou que la documentation doit indiquer explicitement que ce n'est pas le cas. J'ai simplement supposé que la fonctionnalité était une raison essentielle pour laquelle la méthode timestamps() existe.

La méthode timestamps() est inutile pour moi car impossible de définir on update current_timestamp .

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

koskimas picture koskimas  ·  3Commentaires

mattgrande picture mattgrande  ·  3Commentaires

npow picture npow  ·  3Commentaires

ghost picture ghost  ·  3Commentaires

hyperh picture hyperh  ·  3Commentaires