我们是否可以始终使用 knex 和 postgres 将日期列作为字符串(varchar)获取?

2023-12-21

我在 postgres 数据库中有一个列,类型为date。它是一个像生日一样的列,只是一个日期,不需要有时间部分。

当使用 knex 获取此列时,结果是一个 javascript Date 对象。大概是在做new Date(row.birthday),这是发送给客户端的结果。

现在的问题是客户端收到的值采用标准 ISO 8601 格式,其中包含时间部分和Z。当客户端尝试从此字符串创建新的 Date 对象时,客户端可能会根据客户端所在位置获得错误的日期值。

例如:

Date: 2018-06-15
Date sent to client: 2018-06-15T00:00:00Z

Client in +5:00     | Client in -5:00
2018-06-16 05:00:00 | 2018-05-15 10:00:00

如果服务器采用 UTC,这很好,我们只需添加客户端的时区偏移量并获取原始日期,但这感觉有点脆弱,并且在本地开发期间(不是 UTC)会中断。

一个简单的解决方案是将日期部分作为字符串发送给客户端。但这需要将日期存储为varchar在服务器中,这是我们不想做的。我们将失去日期格式约束,并使使用 SQL 进行基于日期的计算变得更加困难。

我们可以将该列转换为varchar当选择列时,但我们需要在每次获取该表时保持冷静。这也意味着我们需要绕过 ORM(书架)来处理这个表。

有没有一种简单的方法可以在 knex 或 bookshelf 或 postgres 本身中指定列需要存储为date,具有所有附带的约束,但始终被获取为varchar?


node-postgres 驱动程序是实际根据日期列发送的数据创建 Date() 对象的部分(https://node-postgres.com/features/types#date-timestamp-timestamptz https://node-postgres.com/features/types#date-timestamp-timestamptz)

使用 postgres,您可以修改 node-pg 的类型解析器,如此处所述https://github.com/brianc/node-pg-types https://github.com/brianc/node-pg-types

日期类型的 oid 为 1082 可以通过以下查询获取

select typname, oid, typarray from pg_type where typname = 'date' order by oid;

因此,要覆盖以字符串形式传递的日期类型,在设置数据库连接之前执行此操作就足够了(我想可以在 knexfile.js 中执行此操作):

var types = require('pg').types;
// override parsing date column to Date()
types.setTypeParser(1082, val => val); 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我们是否可以始终使用 knex 和 postgres 将日期列作为字符串(varchar)获取? 的相关文章

随机推荐