aas*_*ah7 19 javascript postgresql knex.js
我正在使用Knex.JS迁移工具.但是,在创建表时,我希望updated_at在数据库中更新记录时,会自动更新一个名为column的列.
例如,这是一个表:
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");
})
Run Code Online (Sandbox Code Playgroud)
在created_at与updated_at列默认为创建记录的时间,这是罚款.但是,当更新该记录时,我希望该updated_at列显示自动更新的新时间.
我宁愿不用原始的postgres写.
谢谢!
Ric*_*her 25
本尼的回答是完全正确的.但是,我注意到你特别提到了Postgres,在这种情况下,他的psql语法对你不起作用.这是我成功使用的方法.
如果您按设定顺序拥有多个迁移文件,则可能需要人为地更改文件名中的日期戳以使其首先运行(或者只是将其添加到第一个迁移文件中).如果无法回滚,则可能需要手动执行此步骤knex.raw.但是,对于新项目:
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)
Run Code Online (Sandbox Code Playgroud)
现在,该功能应该可用于所有后续迁移.
knexfile.js触发器帮助器我发现如果我可以避免在迁移文件中重复大块SQL,那就更有表现力了.我已经DROP TRIGGER在这里使用了,但是如果你不喜欢这样,你可以在任何地方定义它.
module.exports = {
development: {
// ...
},
production: {
// ...
},
onUpdateTrigger: table => `
CREATE TRIGGER ${table}_updated_at
BEFORE UPDATE ON ${table}
FOR EACH ROW
EXECUTE PROCEDURE on_update_timestamp();
`
}
Run Code Online (Sandbox Code Playgroud)
最后,我们可以相当方便地定义自动更新触发器:
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')
Run Code Online (Sandbox Code Playgroud)
请注意,删除表足以摆脱触发器:我们不需要显式psql.
这一切似乎都是很多工作,但是如果您想要避免使用ORM,那么一旦完成它就会非常"一劳永逸".
您可以使用时间戳创建knex迁移:
exports.up = (knex, Promise) => {
return Promise.all([
knex.schema.createTable('table_name', (table) => {
table.increments();
table.string('name');
table.timestamps(false, true);
table.timestamp('deleted_at').defaultTo(knex.fn.now());
})
]);
};
exports.down = (knex, Promise) => {
return Promise.all([
knex.schema.dropTableIfExists('table_name')
]);
};
Run Code Online (Sandbox Code Playgroud)
使用时间戳,将创建一个数据库模式,该模式添加一个created_at和updated_at列,每个包含一个初始时间戳.
要使updated_at列保持最新,您需要knex.raw:
table.timestamp('updated_at').defaultTo(knex.raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
Run Code Online (Sandbox Code Playgroud)
为了跳过knex.raw解决方案,我建议使用像Objection.js这样的高级ORM .使用Objection.js,您可以实现自己的BaseModel,然后更新updated_at列:
Something.js
const BaseModel = require('./BaseModel');
class Something extends BaseModel {
constructor() {
super();
}
static get tableName() {
return 'table_name';
}
}
module.exports = Something;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
资料来源:http://vincit.github.io/objection.js/#timestamps
小智 -4
可以直接使用这个功能
table.timestamps()
Run Code Online (Sandbox Code Playgroud)
这将默认创建“created_at”和“updated_at”列并相应地更新它们
https://knexjs.org/#Schema-timestamps
| 归档时间: |
|
| 查看次数: |
8183 次 |
| 最近记录: |