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

Knex更新JSON列保留原有数据及插入更新异常问题求助

Knex操作JSON列更新及insert误用问题解决

1. JSON列更新不丢失原有数据

直接覆盖JSON列会丢失原有字段,需要利用对应数据库的JSON合并函数,通过Knex的raw方法调用:

PostgreSQL(jsonb类型推荐)

使用||运算符合并JSON对象,保留原有字段,替换新对象中同名的键:

const value = await knex("orders")
  .update({
    delivery_status: knex.raw("delivery_status || ?::jsonb", [JSON.stringify(delivery_status)]),
    source_latlong: knex.raw("source_latlong || ?::jsonb", [JSON.stringify(source_latlong)])
  })
  .where({ order_id: req.params.order_id });

如果仅需更新JSON中的特定字段,可用jsonb_set精准修改:

// 例:更新delivery_status中的status字段
const value = await knex("orders")
  .update({
    delivery_status: knex.raw("jsonb_set(delivery_status, '{status}', ?)", [JSON.stringify(newStatus)])
  })
  .where({ order_id: req.params.order_id });

MySQL

使用JSON_MERGE_PATCH函数合并对象,相同键会被新值覆盖,不同键保留:

const value = await knex("orders")
  .update({
    delivery_status: knex.raw("JSON_MERGE_PATCH(delivery_status, ?)", [JSON.stringify(delivery_status)]),
    source_latlong: knex.raw("JSON_MERGE_PATCH(source_latlong, ?)", [JSON.stringify(source_latlong)])
  })
  .where({ order_id: req.params.order_id });

若仅修改特定字段,用JSON_SET:

// 例:更新source_latlong中的lng字段
const value = await knex("orders")
  .update({
    source_latlong: knex.raw("JSON_SET(source_latlong, '$.lng', ?)", [newLng])
  })
  .where({ order_id: req.params.order_id });

2. insert加where生成新记录的问题

insert语句的核心是插入新行,Knex中给insert附加where条件不会修改已有记录,只会尝试插入符合条件的新行(若order_id是主键/唯一键会触发冲突)。

正确更新已有记录

直接使用update语句:

const updateResult = await knex("orders")
  .update({
    route_latlong: JSON.stringify(source_latlong)
  })
  .where({ order_id: req.params.order_id });

实现“存在则更新,不存在则插入”

如果需要这个逻辑,根据数据库类型用对应语法:

PostgreSQL

const upsertResult = await knex("orders")
  .insert({
    order_id: req.params.order_id,
    route_latlong: JSON.stringify(source_latlong),
    // 其他必填字段需补充
  })
  .onConflict("order_id")
  .merge({ route_latlong: JSON.stringify(source_latlong) });

MySQL

const upsertResult = await knex("orders")
  .insert({
    order_id: req.params.order_id,
    route_latlong: JSON.stringify(source_latlong),
    // 其他必填字段需补充
  })
  .onDuplicateKeyUpdate({
    route_latlong: JSON.stringify(source_latlong)
  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 14:30:52