squ*_*eim 3 javascript postgresql pg bookshelf.js knex.js
我在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
Run Code Online (Sandbox Code Playgroud)
如果服务器是UTC,这很好,我们可以添加客户端的时区偏移并获取原始日期,但这感觉有点脆弱,并且在本地开发期间(不是UTC)中断.
一个简单的解决方案是将日期部分作为字符串发送给客户端.但这需要将日期存储varchar在服务器中,我们不想这样做.我们将丢失日期格式约束,并且将使用SQL进行基于日期的计算变得更加困难.
我们可以varchar在选择列时强制转换列,但是每次获取此表时我们都需要考虑这一点.这也意味着我们需要绕过ORM(Bookshelf)来处理这个表.
是否有一种简单的方法可以在knex或书架或postgres本身中指定列需要存储为date,具有所有附带的约束,但总是被提取为varchar?
node-postgres驱动程序是从日期列发送的数据实际创建Date()对象的部分(https://node-postgres.com/features/types#date-timestamp-timestamptz)
使用postgres,您可以修改node-pg的类型解析器,如https://github.com/brianc/node-pg-types中所述
可以使用以下查询获取日期类型类型的oid,即1082
select typname, oid, typarray from pg_type where typname = 'date' order by oid;
Run Code Online (Sandbox Code Playgroud)
因此要覆盖要作为字符串传递的日期类型,在设置数据库连接之前就足以执行此操作(我想可以在knexfile.js中执行此操作):
var types = require('pg').types;
// override parsing date column to Date()
types.setTypeParser(1082, val => val); 
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           1124 次  |  
        
|   最近记录:  |