簡體   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

嗨,我正在使用帶有 Postgres 數據庫的 Sequelize

所以我試圖將 sequelize createdAt 和 updatedAt 列上的日期格式化為YYYY-MM-DD HH:mm:ss以及將列保持為 snake_case 而不是駝峰式,因此它們將被created_atupdated_at我怎樣才能實現這一點? 我嘗試了以下方法:

    createdAt: {
      type: DataTypes.DATE,
      allowNull: false,
      defaultValue: moment.utc().format('YYYY-MM-DD HH:mm:ss'),
      field: 'created_at'
    },

或者

    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',
    },

不工作,我收到此錯誤

          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

這是上面定義的整個表格是我確定的我需要幫助的內容

  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
  });

謝謝

今天 Sequelize 文檔在這里不起作用是它的 webarchive

https://web.archive.org/web/20200731154157/http://sequelize.org/master/index.html

據我了解,您的問題包含一些子問題:

  • Sequelize 表列下划線名稱;
  • 序列化日期格式;
  • 片刻的用法;

這是我剛剛得到的一些工作示例(具有上述要求):

有一個像這樣的續集遷移:

'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');
    }
};

有一個像這樣的續集模型:

'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'
    });
};

不要忘記根據需要重命名表名,這里是“項目”。

似乎在 github發布了一個帶有續集“下划線”屬性的問題。 無論如何它對我有用,因為其他屬性有一個小技巧,所以就這樣做,我相信它應該可以工作(Sequelize 版本對我來說是“^5.22.3”)。

我使用過的來源:

如果需要,請隨意編輯和優化(我在 get() 方法中做了一些小的編輯,以獲得所需的確切格式,無論如何我更喜歡使用 moment 作為列訪問器)。

解決方案

至於上面的get()方法只會將格式化的值返回給客戶端,但不會將其保存到數據庫中。 我找到了三個選項來將其保存到數據庫中,因此對於遇到類似問題的任何人來說,這個問題的解決方案。

1. 首選

node_modules/sequelize/lib/data-types.js 里面

我們要修改下面的代碼

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. 第二種選擇

如果您不接觸 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;

所以這兩個選項更像是全局方式,因此格式將適用於您的所有模型。

3. 第三個選項

最后的選擇是使用鈎子為每個模型做這件事

例子:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM