You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sequelize v5 关联表字段参与PostgreSQL WHERE子句datetime运算求助

错误原因

  • 前两种写法触发NaN的原因:sequelize.fn、sequelize.col是数据库层面执行的标识,你把它们直接放到JS的减法运算中,JS会在SQL生成阶段就提前执行算术操作,无法识别这两个方法的返回值,最终得到NaN代入SQL。
  • 第三种写法报epoch列不存在的原因:PostgreSQL中字符串用单引号包裹,反引号是MySQL的语法,你写的epoch会被PG识别为列名而非date_part的参数。

正确实现

写法1:直接用sequelize.literal对齐原生SQL逻辑(最稳妥,不会踩Sequelize语法糖的坑)

const { Op } = require('sequelize');

const getPendingOrders = () => OrderHeader.findAll({
  where: [
    // 直接写和原生SQL完全一致的条件,注意PG语法用单引号包字符串,双引号包表/列名避免大小写问题
    sequelize.literal(`date_part('epoch', "OrderHeader"."updated_at") + "sla_shipping_rules"."secondary_tax_timeout_hour" < date_part('epoch', now())`)
  ],
  include: {
    attributes: ['secondary_tax_timeout_hour'],
    model: SlaShippingRules,
    as: 'sla_shipping_rules',
    on: { shipping_method: { [Op.eq]: sequelize.col('OrderHeader.shipping_method') } },
    required: true,
  },
});

写法2:纯Sequelize方法实现(尽量少用原生SQL片段)

如果不想写完整的literal语句,可以用sequelize.where来拼接数据库层面的运算和比较:

const { Op } = require('sequelize');

const getPendingOrders = () => OrderHeader.findAll({
  where: sequelize.where(
    // 左边:order_header.updated_at的时间戳 + 超时时长
    sequelize.literal(`date_part('epoch', "OrderHeader"."updated_at") + "sla_shipping_rules"."secondary_tax_timeout_hour"`),
    Op.lt,
    // 右边:当前时间戳
    sequelize.fn('date_part', 'epoch', sequelize.fn('now'))
  ),
  include: {
    attributes: ['secondary_tax_timeout_hour'],
    model: SlaShippingRules,
    as: 'sla_shipping_rules',
    on: { shipping_method: { [Op.eq]: sequelize.col('OrderHeader.shipping_method') } },
    required: true,
  },
});

注意:如果你的secondary_tax_timeout_hour字段存的是小时单位,需要在计算时乘以3600转成秒才能和date_part('epoch')返回的秒数匹配,原生SQL可正常执行说明你的字段本身存的是秒数则无需调整。

内容的提问来源于stack exchange,提问作者RageQuitter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:18:02