代码如下:
export const modifyTickLiquidity = (amountGross, amountNet, tickIndex, poolId, chainId, timestamp) => {
const formattedDate: string = dayjs(timestamp * 1000).format('YYYY-MM-DD HH:mm:ss');
console.log(formattedDate)
return prisma.tickInfo.updateMany({
where: {
chainId: chainId,
poolId: poolId,
tickIndex: parseInt(tickIndex),
updatedAt: {
lt:formattedDate
},
},
data: {
liquidityGross: {
increment: amountGross,
},
liquidityNet: {
increment: amountNet,
},
},
});
};
formattedDate字段打印为2023-06-10 19:04:18
运行报错如下:
Argument updatedAt: Got invalid value
{
lt: '2023-06-10 19:04:18'
}
on prisma.updateManytickInfo. Provided Json, expected DateTimeNullableFilter or DateTime or Null.
也就是说updatedAt后面应该传递DateTimeNullableFilter,DateTime或者null,但是我们传递了json,
我们点开DateTimeNullableFilter,看下里面的结构:
export type DateTimeNullableFilter = {
equals?: Date | string | null
in?: Enumerable<Date> | Enumerable<string> | Date | string | null
notIn?: Enumerable<Date> | Enumerable<string> | Date | string | null
lt?: Date | string
lte?: Date | string
gt?: Date | string
gte?: Date | string
not?: NestedDateTimeNullableFilter | Date | string | null
}
也就是说updatedAt后面传递一个结构体,结构体里面的lt后面可以传递Date或者是String,而实际上我们传递的就是String,理论上来说不应该出现这样的错误。
我们先把string换成Date试一下:
export const modifyTickLiquidity = (amountGross, amountNet, tickIndex, poolId, chainId, timestamp) => {
// const formattedDate: string = dayjs(timestamp * 1000).format('YYYY-MM-DDTHH:mm:ss')+'Z';
const formattedDate = new Date(timestamp*1000)
return prisma.tickInfo.updateMany({
where: {
chainId: chainId,
poolId: poolId,
tickIndex: parseInt(tickIndex),
updatedAt: {
lt:formattedDate
},
},
data: {
liquidityGross: {
increment: amountGross,
},
liquidityNet: {
increment: amountNet,
},
},
});
};
这样确实可以正常运行:
SQL: UPDATE `mine_field`.`tick_info` SET `liquidity_gross` = (`mine_field`.`tick_info`.`liquidity_gross` + ?), `liquidity_net` = (`mine_field`.`tick_info`.`liquidity_net` + ?) WHERE (`mine_field`.`tick_info`.`chain_id` = ? AND `mine_field`.`tick_info`.`pool_id` = ? AND `mine_field`.`tick_info`.`tick_index`
= ? AND `mine_field`.`tick_info`.`updated_at` < ?)
Parameters: [9532467375635,-76939622972275360000,137,"0x6b75f2189f0e11c52e814e09e280eb1a9a8a094a",-335190,"2023-06-10 11:04:18 UTC"]
但是我们观察到"2023-06-10 11:04:18 UTC"比我们需要的时间少了8个小时,这个问题可以手动增加8个小时的时间戳解决。
//const formattedDate = new Date(timestamp*1000)
const formattedDate = new Date(timestamp*1000 + 8 * 60 * 60 * 1000)
那么现在我们需要探究一下,传递string的时候明明符合DateTimeNullableFilter结构体的字段定义,为什么还会报错呢。
以下是gitHub上的一段讨论。
This is intended. Prisma will only accept DateTime in ISO 8061 format(https://en.wikipedia.org/wiki/ISO_8601).
If you want use another format, you can should parse it and convert it into a javascript Date object as suggested @navicstein. We will then internally call
toISOString()
on that Date object and pass it to the database.
大体的意思就是,这是官方有意为之,如果要传递string必须使用iso形式的时间格式。
//const formattedDate: string = dayjs(timestamp * 1000).format('YYYY-MM-DD HH:mm:ss');
const formattedDate: string = dayjs(timestamp * 1000).format('YYYY-MM-DDTHH:mm:ss')+'Z';
console.log(formattedDate)
formattedDate打印为 2023-06-10T19:04:18Z,方法正常运行!
所以,要解决这个问题有两个方案
1.使用Date,要注意时区
2.使用iso的时间格式。
吐槽一下chatGpt,不懂装懂,一本正经的胡说八道,有时候还是需要手动搜索来弥补。