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

如何使用Sequelize向PostgreSQL的JSONB列数组推送数据

解决Sequelize批量更新PostgreSQL JSONB数组的问题

问题原因

你原来的写法直接将expenseEditHistory赋值为普通对象,Sequelize会把其中的sequelize.fn('array_append', ...)序列化为字符串,而非执行对应的SQL函数,导致无法正确追加JSONB数组元素。PostgreSQL的JSONB类型需要使用专门的JSON函数来修改内部结构。

解决方案

需要利用PostgreSQL的jsonb_set函数来同时更新last_updated_by字段和追加history数组元素,结合Sequelize的literal或fn方法实现安全的批量更新。

方法一:使用sequelize.literal(推荐,更清晰且防SQL注入)

await Expenses.update(
    {
        isDeleted: true,
        expenseEditHistory: sequelize.literal(`
            jsonb_set(
                // 先更新last_updated_by字段
                jsonb_set(
                    // 处理字段为空的情况,初始化默认结构
                    coalesce(expenseEditHistory, '{"history": []}'::jsonb),
                    '{last_updated_by}',
                    $1::jsonb
                ),
                // 追加history数组元素
                '{history}',
                coalesce(expenseEditHistory->'history', '[]'::jsonb) || $2::jsonb
            )
        `)
    },
    {
        where: {
            id: {
                [Op.in]: expenseIDXasTableID,
            },
        },
        // 绑定参数,避免SQL注入
        bind: [req.user.id, editHistoryItem]
    }
);

方法二:使用嵌套的sequelize.fn

await Expenses.update(
    {
        isDeleted: true,
        expenseEditHistory: sequelize.fn(
            'jsonb_set',
            // 第一步:更新last_updated_by
            sequelize.fn(
                'jsonb_set',
                sequelize.fn('coalesce', sequelize.col('expenseEditHistory'), sequelize.literal(`'{"history": []}'::jsonb`)),
                sequelize.literal(`'{last_updated_by}'`),
                sequelize.cast(req.user.id, 'jsonb')
            ),
            // 第二步:追加history数组元素
            sequelize.literal(`'{history}'`),
            sequelize.fn(
                '||',
                sequelize.fn('coalesce', sequelize.col('expenseEditHistory.history'), sequelize.literal(`'[]'::jsonb`)),
                sequelize.cast(editHistoryItem, 'jsonb')
            )
        )
    },
    {
        where: {
            id: {
                [Op.in]: expenseIDXasTableID,
            },
        }
    }
);

关键说明

  • coalesce函数用于处理expenseEditHistory字段为null的情况,确保即使字段为空也能正常初始化并追加元素。
  • ||操作符是PostgreSQL中JSONB数组的追加方式,比array_append更适配JSONB类型。
  • 使用bind参数或cast方法确保数据类型正确转换为JSONB,同时避免SQL注入风险。

内容的提问来源于stack exchange,提问作者SaaD Ibne Jamal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:54:52