如何在 Knex.js 中正确设置“updatedAt”时间戳?

Posted

技术标签:

【中文标题】如何在 Knex.js 中正确设置“updatedAt”时间戳?【英文标题】:How to set `updatedAt` timestamp in Knex.js properly? 【发布时间】:2019-12-01 16:31:33 【问题描述】:

我正在使用 Knex.js(0.19.0) 和 PostgreSQL(11-alpine, pg@7.11.0) 做一个 REST 教程,我注意到当我发出 PUT 请求和更新数据。

目前这是我的users 表:

// users_migration.js

exports.up = function(knex) 
  return knex.schema.createTable('users', function(table) 
    table
      .increments('id')
      .primary()
      .unsigned();
    table.string('firstName');
    table
      .string('lastName')
      .index()
      .notNullable();
    table
      .string('email')
      .unique()
      .index()
      .notNullable();
    table.string('password').notNullable();
    table.string('role').defaultTo('STAFF');
    table.boolean('isActive').defaultTo(false);
    table.timestamp('createdAt').defaultTo(knex.fn.now());
    table.timestamp('updatedAt').defaultTo(knex.fn.now());
  );
;

我试过这个:

    table.timestamp('createdAt').defaultTo(knex.raw('CURRENT_TIMESTAMP'));
    table
      .timestamp('updatedAt')
      .defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));

但它也不起作用。

如何让它发挥作用?请帮忙。

【问题讨论】:

【参考方案1】:

postgresql 不支持语法CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

使updatedAt在更新列时自动更新的唯一方法是使用触发器。

这可能有效(从Update timestamp when row is updated in PostgreSQL 复制粘贴):

exports.up = function(knex) 
  return knex.schema.createTable('users', function(table) 
    ...
    table.timestamp('updatedAt').defaultTo(knex.fn.now());
  )
  .raw(`
    CREATE OR REPLACE FUNCTION update_updated_at_column()
    RETURNS TRIGGER AS $$
    BEGIN
     NEW."updatedAt"=now(); 
     RETURN NEW;
    END;
    $$ language 'plpgsql';
  `)
  .raw(`
    CREATE TRIGGER update_user_updated_at BEFORE UPDATE
    ON ?? FOR EACH ROW EXECUTE PROCEDURE 
    update_updated_at_column();
  `, ['users']);

;

如果有语法错误或类似问题,请告诉我。

【讨论】:

【参考方案2】:

根据文档,

table.timestamps(true, true);

单独添加 created_at 和 updated_at。 第二个参数为真,指的是现在的日期。

来源:https://knexjs.org/#Schema-timestamps

【讨论】:

【参考方案3】:

定义架构时,可以使用timestamps() 方法自动添加created_atupdated_at 列。

knex.schema.createTable('users', (table) => 
  table.timestamps(true, true);
);
timestamps — table.timestamps([useTimestamps], [defaultToNow])

在数据库中添加 created_at 和 updated_at 列,将每个列设置为日期时间类型。当 true 作为第一个参数传递时,将使用时间戳类型。当 true 作为第二个参数传递时,两列默认不为 null 并使用当前时间戳。请注意,在 mysql 上 .timestamps() 只有秒精度,要获得更好的精度,请直接使用 .datetime 或 .timestamp 方法。

来源:https://knexjs.org/#Schema-timestamps

【讨论】:

为什么设置时间的格式很奇怪? 2022-01-22 03:25:28.464542+00

以上是关于如何在 Knex.js 中正确设置“updatedAt”时间戳?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Knex.js 和 PostgreSQL 设置 Docker

带有 Express 的 Knex.js,如何在 knex.commit 后跟 knex.select 查询?

如何在 knex.js 迁移中链接承诺

如何在 Knex JS 中使用 IS NOT NULL

如何在 knex.js 模式的增量列中添加一个字母?

使用 Oracle 程序 - Node.js Knex.js