Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Knex.JS自动更新触发器_Javascript_Postgresql_Knex.js - Fatal编程技术网

Javascript Knex.JS自动更新触发器

Javascript Knex.JS自动更新触发器,javascript,postgresql,knex.js,Javascript,Postgresql,Knex.js,我正在使用迁移工具。但是,在创建表时,我希望在处有一个名为updated\u的列,当数据库中的记录更新时,该列会自动更新 例如,下面是一个表: knex.schema.createTable('table_name', function(table) { table.increments(); table.string('name'); table.timestamp("created_at").defaultTo(knex.fn.now()); table.ti

我正在使用迁移工具。但是,在创建表时,我希望在处有一个名为
updated\u的列,当数据库中的记录更新时,该列会自动更新

例如,下面是一个表:

knex.schema.createTable('table_name', function(table) {
    table.increments();
    table.string('name');
    table.timestamp("created_at").defaultTo(knex.fn.now());
    table.timestamp("updated_at").defaultTo(knex.fn.now());
    table.timestamp("deleted_at");
})
created_at
updated_at
列默认为创建记录的时间,这是正常的。但是,当该记录被更新时,我希望
updated_at
列显示自动更新的新时间

我宁愿不写原始的博士后


谢谢

您可以直接使用此功能

table.timestamps()
默认情况下,这将创建“created_at”和“updated_at”列,并相应地更新它们


这不是Knex的功能。Knex只创建列,但不为您保持最新

但是,如果使用书架表单,则可以指定表具有时间戳,并且它将按预期设置和更新列:


您可以使用以下方法创建knex迁移:

将创建一个数据库架构,其中在
处添加一个
created\u列和在
处添加一个
updated\u列,每个列都包含一个初始时间戳

要使
列的
保持最新,您需要
knex.raw

table.timestamp('updated_at').defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
要跳过
knex.raw
解决方案,我建议使用类似的高级ORM。使用,您可以实现自己的
BaseModel
,然后在
列更新
updated\u:

Something.js

const BaseModel = require('./BaseModel');

class Something extends BaseModel {
  constructor() {
    super();
  }

  static get tableName() {
    return 'table_name';
  }
}

module.exports = Something;
BaseModel

const knexfile = require('../../knexfile');
const knex = require('knex')(knexfile.development);
const Model = require('objection').Model;

class BaseModel extends Model {
  $beforeUpdate() {
    this.updated_at = knex.fn.now();
  }
}

module.exports = BaseModel;

来源:

对于Postgres,您需要。这是我成功使用的一种方法

添加一个函数 如果您有多个按设定顺序排列的迁移文件,则可能需要人为地更改文件名中的日期戳,以使其首先运行(或仅将其添加到第一个迁移文件中)。如果无法回滚,则可能需要通过
psql
手动执行此步骤。但是,对于新项目:

const ON_UPDATE_TIMESTAMP_FUNCTION = `
  CREATE OR REPLACE FUNCTION on_update_timestamp()
  RETURNS trigger AS $$
  BEGIN
    NEW.updated_at = now();
    RETURN NEW;
  END;
$$ language 'plpgsql';
`

const DROP_ON_UPDATE_TIMESTAMP_FUNCTION = `DROP FUNCTION on_update_timestamp`

exports.up = knex => knex.raw(ON_UPDATE_TIMESTAMP_FUNCTION)
exports.down = knex => knex.raw(DROP_ON_UPDATE_TIMESTAMP_FUNCTION)
现在,该功能应可用于所有后续迁移

定义一个
knex.raw
触发器辅助对象 如果可以避免的话,我发现不在迁移文件中重复大量SQL更具表现力。我在这里使用了
knexfile.js
,但是如果您不想把它复杂化,您可以在任何地方定义它

module.exports = {
  development: {
    // ...
  },

  production: {
    // ...
  },

  onUpdateTrigger: table => `
    CREATE TRIGGER ${table}_updated_at
    BEFORE UPDATE ON ${table}
    FOR EACH ROW
    EXECUTE PROCEDURE on_update_timestamp();
  `
}
使用助手 最后,我们可以非常方便地定义自动更新触发器:

const { onUpdateTrigger } = require('../knexfile')

exports.up = knex =>
  knex.schema.createTable('posts', t => {
    t.increments()
    t.string('title')
    t.string('body')
    t.timestamps(true, true)
  })
    .then(() => knex.raw(onUpdateTrigger('posts')))

exports.down = knex => knex.schema.dropTable('posts')
请注意,删除表就足以摆脱触发器:我们不需要显式的
删除触发器


这一切看起来可能需要做很多工作,但一旦你完成了它,它就相当于“设置并忘记”,如果你想避免使用ORM,它非常方便。

这是我在Mysql 5.6+中的做法

我没有使用table.timestamp的原因是我使用了DATETIME而不是timestamp

table.dateTime('created_on')
        .notNullable()
        .defaultTo(knex.raw('CURRENT_TIMESTAMP'))

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

我讨厌人们投票否决一个看起来很好、没有评论的答案。我怀疑
timestamps()
并没有像文档中描述的那样工作,但可能他们只是心情不好或是其他什么。
table.timestamps()
需要转换为
table.timestamps(false,true)
以确保在未提供数据时使用当前时间戳。即使
table.timestamps(false,true)时,它不会更新
列中的
updated\u。Upvote for objective.js。node.js的ORM真不错,答案太棒了!它不仅有效,而且是如何向postgres添加函数的好例子。谢谢这是一个奇妙的解决方案,男孩,它是干净的。谢谢,里奇!回答得很好。是否需要在knexfile上编写方法
onUpdateTrigger
。我只是发现使用(或接近)knexfile.js
存储这些东西更容易。
table.dateTime('created_on')
        .notNullable()
        .defaultTo(knex.raw('CURRENT_TIMESTAMP'))

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