[英]Sequelize How do you format date to YYYY-MM-DD HH:mm:ss and keep the columns as snake case
Hi I am using Sequelize with a Postgres Database嗨,我正在使用带有 Postgres 数据库的 Sequelize
So I am trying to format date on the sequelize createdAt and updatedAt columns as YYYY-MM-DD HH:mm:ss
As well as keeping the columns as snake_case not camelcase so they would be created_at
and updated_at
How can I achieve this?所以我试图将 sequelize createdAt 和 updatedAt 列上的日期格式化为YYYY-MM-DD HH:mm:ss
以及将列保持为 snake_case 而不是驼峰式,因此它们将被created_at
和updated_at
我怎样才能实现这一点? I have tried the following:我尝试了以下方法:
createdAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: moment.utc().format('YYYY-MM-DD HH:mm:ss'),
field: 'created_at'
},
or或者
createdAt: {
type: DataTypes.DATE,
defaultValue: sequelize.NOW,
set(value) {
return value.toISOString().replace(/\..+/g, '')
// coming in the db as 2021-10-31 01:34:48.81+00 so wanted to remove evrything after the dot
},
name: 'createdAt',
field: 'created_at',
},
Is not working and I am getting this error不工作,我收到此错误
throw new Error(`Value for "${key}" option must be a string or a boolean, got ${typeof this.options[key]}`);
^
Error: Value for "createdAt" option must be a string or a boolean, got object
Here is the whole table defined above is what I have pinpointed which I need help with这是上面定义的整个表格是我确定的我需要帮助的内容
const Supplier = sequelize.define('Supplier', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
validate: {
len: [1, 50]
}
},
description: {
type: DataTypes.STRING,
allowNull: true,
},
}, {
tableName: 'suppliers',
timestamps: true,
createdAt: {
type: DataTypes.DATE,
defaultValue: sequelize.NOW,
set(value) {
return value.toISOString().replace(/\..+/g, '')
},
name: 'createdAt',
field: 'created_at',
},
updatedAt: {
type: DataTypes.DATE,
defaultValue: sequelize.NOW,
set(value) {
return value.toISOString().replace(/\..+/g, '')
},
field: 'updated_at',
},
// freezeTableName: true
// paranoid: true
});
Thanks谢谢
Today Sequelize docs is not working here is a webarchive's for it今天 Sequelize 文档在这里不起作用是它的 webarchive
https://web.archive.org/web/20200731154157/http://sequelize.org/master/index.html https://web.archive.org/web/20200731154157/http://sequelize.org/master/index.html
As I understand your question contains some subquetions:据我了解,您的问题包含一些子问题:
Here's some working example (with requirements mentioned above) I've just got:这是我刚刚得到的一些工作示例(具有上述要求):
Have a sequelize migration like this:有一个像这样的续集迁移:
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('items', {
// ...
created_at: {
allowNull: false,
type: Sequelize.DATE
},
// ...
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('items');
}
};
Have a sequelize model like this:有一个像这样的续集模型:
'use strict';
// WITH moment
// const moment = require('moment');
module.exports = (sequelize, DataTypes) => {
// const now = new Date();
return sequelize.define('Item', {
// ...
created_at: {
allowNull: false,
// defaultValue: now,
type: DataTypes.DATE,
get() {
// 1. WITHOUT moment
const date = new Date(`${this.dataValues.created_at}`);
return `${date.toISOString().split('T')[0]} ${date.toLocaleTimeString([], {month: '2-digit', timeStyle: 'medium', hour12: false})}`;
// 2. WITHOUT moment (another solution)
// const parts = date.toISOString().split('T');
// return `${parts[0]} ${parts[1].substring(0, 8)}`;
// 3. WITH moment
// return moment(this.dataValues.created_at).format('D MM YYYY HH:mm:ss'); // 'D MMM YYYY, LT'
}
},
// ...
}, {
tableName: 'items',
freezeTableName: true,
// underscored: true,
timestamps: false,
charset: 'utf8',
collate: 'utf8_general_ci'
});
};
Don't forget to rename your table name for your needs, here is "items".不要忘记根据需要重命名表名,这里是“项目”。
Seems there is an issue posted on github with sequelize "underscored" property.似乎在 github上发布了一个带有续集“下划线”属性的问题。 Anyway it worked for me, cuz there is a small trick with other properties, so just do like that and I believe it should work (Sequelize version for me was "^5.22.3").无论如何它对我有用,因为其他属性有一个小技巧,所以就这样做,我相信它应该可以工作(Sequelize 版本对我来说是“^5.22.3”)。
Sources I've used:我使用过的来源:
Feel free to edit and optimize if you need (I did some small edits in the get() method for getting the exact format as you want, anyway I prefer to use moment as a column accessor).如果需要,请随意编辑和优化(我在 get() 方法中做了一些小的编辑,以获得所需的确切格式,无论如何我更喜欢使用 moment 作为列访问器)。
Solution解决方案
As for above the get()
method will only return the value as formatted to the client but it wont save it to the database.至于上面的get()
方法只会将格式化的值返回给客户端,但不会将其保存到数据库中。 I have found three options to make it save to the database thus the solution for this issue for anyone experiencing something similar.我找到了三个选项来将其保存到数据库中,因此对于遇到类似问题的任何人来说,这个问题的解决方案。
1. First Option 1. 首选
Inside the node_modules/sequelize/lib/data-types.js在node_modules/sequelize/lib/data-types.js 里面
We have to modify the following code我们要修改下面的代码
DATE.prototype._stringify = function _stringify(date, options) {
date = this._applyTimezone(date, options);
// Z here means current timezone, _not_ UTC
// return date.format('YYYY-MM-DD HH:mm:ss.SSS Z');// from this to the below code
return date.format('YYYY-MM-DD HH:mm:ss.SSS'); // to this
};
2. Second Option 2. 第二种选择
If you don't to touch your node_modules folder and do not like option 1, than a somewhat better solution would be to do what you did at option 1 but in your own db.js file:如果您不接触 node_modules 文件夹并且不喜欢选项 1,那么更好的解决方案是执行您在选项 1 中所做的操作,但在您自己的 db.js 文件中:
const { Sequelize } = require('sequelize');
const { DB } = require('../config');
// Override timezone formatting by requiring the Sequelize and doing it here instead
Sequelize.DATE.prototype._stringify = function _stringify(date, options) {
date = this._applyTimezone(date, options);
// Z here means current timezone, _not_ UTC
// return date.format('YYYY-MM-DD HH:mm:ss.SSS Z');
return date.format('YYYY-MM-DD HH:mm:ss Z');
};
const db = new Sequelize(`${DB.DIALECT}://${DB.USER}:${DB.PASS}@${DB.HOST}:${DB.PORT}/${DB.DB}`, {
logging: false
})
module.exports = db;
So this two option is more like global way off doing it so the format will be for all your models.所以这两个选项更像是全局方式,因此格式将适用于您的所有模型。
3. Third Option 3. 第三个选项
Final option is to do it for each single models by using hooks最后的选择是使用钩子为每个模型做这件事
Example:例子:
const Supplier = sequelize.define('Supplier', {
// col attributes
}, {
tableName: 'suppliers',
timestamps: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
hooks : {
beforeCreate : (record, options) => {
record.dataValues.created_at = new Date().toISOString().replace(/T/, ' ').replace(/\..+/g, '');
record.dataValues.updated_at = new Date().toISOString().replace(/T/, ' ').replace(/\..+/g, '');
},
beforeUpdate : (record, options) => {
record.dataValues.updated_at = new Date().toISOString().replace(/T/, ' ').replace(/\..+/g, '');
}
},
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.