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

4

我正在使用 Knex.js (0.19.0) 和 PostgreSQL(11-alpine, pg@7.11.0) 进行 REST 教程,并且在进行 PUT 请求并更新数据时,我发现 updatedAt 列不起作用。

目前这是我的 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'));

但是它还是不起作用。

我该怎么让它起作用?请帮忙。

3个回答

4
在定义模式时,您可以使用timestamps()方法自动添加created_atupdated_at列。
knex.schema.createTable('users', (table) => {
  table.timestamps(true, true);
});

timestamps — table.timestamps([useTimestamps], [defaultToNow])

在数据库上添加created_at和updated_at列,将每个列设置为datetime类型。当第一个参数传递true时,会使用timestamp类型。两个列的默认值都是非空的,并且当第二个参数传递true时,默认使用当前时间戳。请注意,在MySQL上,.timestamps()只有秒精度,要获得更好的精度,请直接使用.precision方法的.datetime或.timestamp方法。
来源:https://knexjs.org/#Schema-timestamps

为什么它使用奇怪的格式设置时间?2022-01-22 03:25:28.464542+00 - Tim Bogdanov
4
@TimBogdanov 今天是你的幸运日,你将学习到 ISO-8601,这可能是存在的最标准(因此最不“奇怪”:))格式:https://en.wikipedia.org/wiki/ISO_8601 - 你能更具体地说明你所说的“奇怪”是什么,以及你的期望是什么吗?如果你阅读链接文档,你会发现如果将第一个参数设置为 false,它将使用 DATETIME 字段而不是 TIMESTAMP,这可能是你所期望的? - cincodenada
ISO-8601的进一步参考资料:https://xkcd.com/1179/ - cincodenada

2

2

postgresql不支持语法CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

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

这可能会起作用(从在PostgreSQL中更新行时更新时间戳复制粘贴):

```sql CREATE OR REPLACE FUNCTION update_table() RETURNS TRIGGER AS $$ BEGIN NEW."updatedAt" = NOW(); RETURN NEW; END; $$ language 'plpgsql';
CREATE TRIGGER update_table_trigger BEFORE UPDATE ON "table_name" FOR EACH ROW EXECUTE FUNCTION update_table(); ```
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']);

};

最初的回答
如果有语法错误或类似的问题,请告诉我。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接