我在将一些数据从PostgreSQL数据库传输到服务时遇到问题。
设置方式如下:
Service1将GraphQL请求发送到Service2询问数据。 Service2将此数据存储在PostgreSQL数据库中,并从该数据库中获取信息。
使用TypeORM和GraphQL的装饰器将数据建模为实体。我遇到问题的确切字段是这样的:
@Column({
nullable: true,
type: 'timestamp'
})
@Field(() => GraphQLISODateTime, {nullable: true})
executed_on: Date
当数据从数据库到达service2时,它存在,所有字段都在那里,并且date字段及其值也存在。
从数据库中获取时的字段:
"executed_on": "2019-10-27T23:00:00.000Z"
从Service1提取的字段:
"executed_on": null
当将其发送到service1时,我可以进行console.log记录数据,然后看到那里的字段。我假设由于GraphQL以JSON格式发送数据,因此date字段成为字符串。现在,当此数据从service1传输到其他位置时,所有executed_on
字段值都为空。我不知道发生这种情况的原因。可能是因为它现在是一个字符串,所以它没有被解析为Date字段?
我发现一种解决方法是循环访问数组中的每个对象,并仅根据当前的字符串值创建一个新的Date对象,但这不是我想要做的事情,因为当我在其他服务中也会发生此过程是从外部REST API提取数据的,所以我猜这将是一个糟糕的设计?我对此很陌生。
任何帮助将不胜感激。
答案 0 :(得分:0)
我面临类似的问题,我认为这是由于GraphQl节点模块中DateTime类型的序列化错误所致。
这是失败的原因:
// node_modules/graphql/execution/execute.js:
completeLeafValue(returnType, result) {
// this returns null even though a correct "value" is being passed in
var serializedResult = returnType.serialize(result);
...
因为它的序列化器由于“ value instanceof Date”而失败,并且只返回null:
serialize(value) {
return value instanceof Date ? value.toISOString() : null;
}
由于某种原因,type = Date被强制转换为“ DateTime”,为什么我还没有弄清楚,但在我看来,它应该抛出一个错误而不是仅仅返回null。
您已经说过:唯一的解决方法/修复是为对象树中的每个Date字段创建一个新的Date(...)对象。
或者分叉原始存储库,并将此代码添加到“ completeLeafValue”方法中:
//node_modules/graphql/execution/execute.js:
completeLeafValue(returnType, result) {
var serializedResult = returnType.serialize(result);
if(completeLeafValue==="DateTime") {
result = new Date(result);
//new Date(...) does not throw and only returns null when it fails
//so we have to check for null
if(result === null) {
throw new Error(`Cannot cast ${result} to Date object`);
}
}
...(rest or original fn)