Sequelize 中的时间戳陷阱及解决方法

阅读时长 8 分钟读完

Sequelize是一个优秀的ORM框架,它支持多种关系型数据库,例如MySQL、PostgreSQL和SQLite等。在开发Web应用程序时,Sequelize可用于管理数据模型,维护数据库结构,并提供方便的查询语言。然而,我们在使用Sequelize构建应用程序时,也会遇到一些困难。本文将介绍Sequelize中的时间戳陷阱及解决方法。

问题背景

在使用Sequelize进行数据模型组织时,通常会定义模型的属性,例如:

在这里,我们定义了一个名为“User”的模型,它具有属性name、age和email。然而,我们经常的需求是需要为记录添加创建时间和更新时间的字段,以便在查询时了解数据被创建和更新的时间。Sequelize提供了两个选项createdAt和updatedAt来处理这个问题,将其添加到我们的模型定义中:

这样,我们的User模型就包含了createdAt和updatedAt两个属性,分别表示记录的创建和更新时间。当Sequelize创建表时,它会自动创建这两个属性及其索引。

问题分析

在使用Sequelize的时间戳功能时,有一些陷阱需要注意。如果我们在定义模型时不指定createdAt和updatedAt的默认值,Sequelize将在每次保存模型时自动设置它们的值。例如:

在这里,我们没有指定createdAt和updatedAt的默认值。当保存一个新的User记录时,Sequelize会自动设置createdAt和updatedAt为当时的时间。

上面的代码将输出创建时间。

然而,在使用Node.js开发时,我们通常需要将时间戳的值与本地时间进行比较。例如,我们可能想查询最近24小时之内创建的记录:

-- -------------------- ---- -------
--------------
  ------ -
    ---------- -
      ------------------ --- --------------- - -- - -- - -- - -----
    -
  -
------------- -- -
  -------------------
---

在上面的代码中,我们使用Sequelize.Op.gt运算符查询最近24小时内创建的用户。

然而,这样的查询方法可能会导致数据不准确。如果我们的服务器位于时区不同的地方,或者用户的电脑时间不准确,那么我们将无法准确地知道何时创建记录。

解决方法

为了避免这个问题,我们需要为时间戳添加一个默认值,并让Sequelize使用UTC时间来定位时间。我们可以将模型定义更改如下:

-- -------------------- ---- -------
----- ---- - ------------------------ -
  ----- -----------------
  ---- ------------------
  ------ -----------------
  ---------- -
    ----- ---------------
    ------------- ---------------------------------------
    ---------- ------
    ----- -
      ------ ------------------------------------------------------------- ----------
    --
  --
  ---------- -
    ----- ---------------
    ------------- ---------------------------------------
    ---------- ------
    ----- -
      ------ ------------------------------------------------------------- ----------
    --
  -
---

在这里,我们使用Sequelize.literal()为createdAt和updatedAt提供了默认值。这个默认值使用MySQL的CURRENT_TIMEtSTAMP函数创建UTC时间。然后,我们使用moment.js库将UTC时间转换为本地时间格式。这样,我们就可以确保时间戳值的准确性。

示例代码

为了方便演示,以下示例代码在MySQL 5.6上运行。您需要在本地MySQL数据库中安装Sequelize和MySQL驱动程序。

-- -------------------- ---- -------
----- --------- - ---------------------
----- ------ - ------------------

----- --------- - --- ----------------- ------- ----------- -
    ----- ------------
    -------- -------
---

----- ---- - ------------------------ -
    ----- -----------------
    ---- ------------------
    ------ -----------------
    ---------- -
        ----- ---------------
        ------------- ---------------------------------------
        ---------- ------
        ----- -
            ------ ------------------------------------------------------------- -----------
        --
    --
    ---------- -
        ----- ---------------
        ------------- ---------------------------------------
        ---------- ------
        ----- -
            ------ ------------------------------------------------------------- -----------
        --
    -
---

---------------- ------ ---- ---------- -- -
    --------------------- - ------ -----------
    ------------- ----- -------- ---- --- ------ ------------------- ------------ -- -
        ----------------------------
        --------------
            ------ -
                ---------- -
                    ------------------ --- --------------- - -- - -- - -- - -----
                -
            -
        ------------- -- -
            -------------------
        ---
    ---
---

如果您运行这个示例,您将会看到准确的时间戳输出。

结论

在使用Sequelize时,请务必牢记时间戳的陷阱。通过为时间戳添加默认值并将其转换为本地时间,我们可以避免数据的不准确性。在开发Web应用程序时,时区和时间戳问题经常是常见的问题,正确处理这些问题对于确保您的应用程序正确性是至关重要的。

参考资料

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67511680050cf9039c1a13d6

纠错
反馈