简体   繁体   English

Sequelize 如何将日期格式化为 YYYY-MM-DD HH:mm:ss 并将列保持为蛇形

[英]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_atupdated_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:据我了解,您的问题包含一些子问题:

  • Sequelize table column underscored names; Sequelize 表列下划线名称;
  • Sequelize date format;序列化日期格式;
  • Usage without moment ;片刻的用法;

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.jsnode_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.

相关问题 如何检查字符串是否为有效日期格式(格式应为:YYYY-MM-DD HH:mm:ss) - how to check the string is valid date format or not (format should be in : YYYY-MM-DD HH:mm:ss) 如何在 javascript 中解析 yyyy-MM-dd HH:mm:ss.SSS 格式的日期? - How to parse yyyy-MM-dd HH:mm:ss.SSS format date in javascript? 如何将“YYYY-MM-DD hh:mm:ss”格式的日期转换为 UNIX 时间戳 - How to convert date in format "YYYY-MM-DD hh:mm:ss" to UNIX timestamp 如何使用 NodeJS 将 UTC 日期格式化为“YYYY-MM-DD hh:mm:ss”字符串? - How to format a UTC date as a `YYYY-MM-DD hh:mm:ss` string using NodeJS? 如何使用JavaScript将数据格式“ YYYY-mm-dd hh:mm:ss”转换为“ dd-mm-YYYY hh:mm:ss”? - How to convert data format “YYYY-mm-dd hh:mm:ss” to “dd-mm-YYYY hh:mm:ss” using javascript? 如何验证 yyyy-mm-dd hh:mm:ss 格式 - How do I validate yyyy-mm-dd hh:mm:ss format 如何将日期格式化为 (dd/mm/yyyy hh:mm:ss) - How to format the date to (dd/mm/yyyy hh:mm:ss) 如何在核心 JavaScript 中将新日期 object 格式化为 MySQL 格式 YYYY-MM-DD hh-mm-ss? - How to format new date object to MySQL format YYYY-MM-DD hh-mm-ss in core JavaScript? Json字符串数组格式日期时间字段-yyyy-MM-dd hh:mm:ss - Json string array format Date Time field - yyyy-MM-dd hh:mm:ss 日期格式为“yyyy-MM-dd'T'HH:mm:ss.SSS'Z'” - Format Date as "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM