Knex: table.timestamps() 应该为 updated_ts 设置 ON UPDATE CURRENT_TIMESTAMP

创建于 2017-02-21  ·  8评论  ·  资料来源: knex/knex

预期的:
table.timestamps()创建updated_ts列时,其 DDL 应为:

timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

实际的:
ON UPDATE CURRENT_TIMESTAMP部分丢失 - updated_ts列永远不会自动更新。

我描述的语法适用于 MySQL,我不确定它在数据库引擎之间的兼容性如何。

最有用的评论

我认为timestamps()需要提供此自动更新功能,或者文档需要明确声明它没有。 我只是假设功能是timestamps()方法存在的关键原因。

所有8条评论

至少对于 postgres 语法并不是那么好:

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

虽然我想为timestamp列使用.autoUpdate() builder 方法,但是为.timestamps()助手启用它也是微不足道的。

看起来 SQLite3 也有可用于实现这一点的触发器。 Oracle 和 mssql 可能也有一些更好的语法,或者至少可以用触发器来完成。

这真是太好了! 目前我们需要依靠书架更新我们的时间戳,对吗?

您可以手动创建日期时间字段(mysql),而不是依赖书架:

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

或者,如果您更喜欢updated_at默认为创建时间:

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

您可以手动创建日期时间字段(mysql),而不是依赖书架:

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

使用您为updated_at 发布且默认为null 的代码仍会为updated_at 插入当前时间戳。

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

此测试失败:

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'));
  });

编辑:
没关系,似乎从模型定义中完全删除hasTimestamps可以解决这个问题。

我们在这里混合了 Knex 和 Bookshelf 问题,但是@Ice32如果您不想使用 Bookshelf 的自动时间戳功能,则必须从模型定义中删除hasTimestamps: ['createdAt', 'updatedAt']@codeclown上面发布的代码

我的解决方案:

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

我认为timestamps()需要提供此自动更新功能,或者文档需要明确声明它没有。 我只是假设功能是timestamps()方法存在的关键原因。

timestamps()方法对我来说没用,因为不能设置on update current_timestamp

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

arconus picture arconus  ·  3评论

lanceschi picture lanceschi  ·  3评论

zettam picture zettam  ·  3评论

marianomerlo picture marianomerlo  ·  3评论

hyperh picture hyperh  ·  3评论