如何使用 knexjs 更新 json 列中具有值的对象的键?
How to update a key of object with value in json column with knexjs?
我正在尝试更新用户 table 中的列,列类型为 json.
列名称是测试。
并且该列包含一个对象默认值,例如
{a: "text", b: 0}
如何在不更改整个列的情况下更新对象键 b
我使用的代码是
knexDb('users').where({
email: email
})
.update({
test: { b: 1 }
})
第二种解决方案
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1])
})
第一个解决方案更改了整个列单元格,测试将仅为 { b: 1 }
第二个解决方案不起作用,它给出了一个错误
function jsonb_set(json, unknown, unknown) does not exist
预期结果
是在不改变整个对象的情况下只更新对象中的某个键值。
PS
我还想更新一个由对象组成的数组,例如上面的对象。
[{a: "text", b: 0}, {c: "another-text", d: 0}]
如果我在 kenxjs 中使用上面的代码,它会将整个数组更新为仅 {b: 1}
PS 经过大量搜索后发现,为了使其工作,我需要将列类型设置为 jsonb,以便上述jsonb_set() 工作
但现在我面临另一个问题
how to update multiple keys using jsonb_set
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1]),
test: knexDb.raw(`jsonb_set(??, '{a}', ?)`, ['test', "another-text"]),
})
第一个查询键 b 现在没有更新,事实上除了最后一个查询键 a
之外所有更新都不起作用,所以有人可以解释为什么吗?
您的问题是您正在覆盖 test
。您传递给 update
的是一个 JS 对象 (docs). You cannot have multiple keys with identical values (docs)。你必须做这样的事情,你用所有原始 SQL 作为 test
.
的值制作 1 个长字符串
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`
jsonb_set(??, '{a}', ?)
jsonb_set(??, '{b}', ?)
`,
['test', "another-text", 'test', 1])
})
可能存在更好的选择 - 如果您必须对多个列执行此操作,那么可读性会更好,就像我在下面包含的那样。在此示例中,包含 jsonb
的列称为 json
.
const updateUser = async (email, a, b) => {
const user = await knexDb('users')
.where({ email })
.first();
user.json.a = a;
user.json.b = b;
const updatedUser = await knexDb('users')
.where({ email })
.update(user)
.returning('*');
return updatedUser;
}
我正在尝试更新用户 table 中的列,列类型为 json.
列名称是测试。
并且该列包含一个对象默认值,例如
{a: "text", b: 0}
如何在不更改整个列的情况下更新对象键 b
我使用的代码是
knexDb('users').where({
email: email
})
.update({
test: { b: 1 }
})
第二种解决方案
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1])
})
第一个解决方案更改了整个列单元格,测试将仅为 { b: 1 }
第二个解决方案不起作用,它给出了一个错误
function jsonb_set(json, unknown, unknown) does not exist
预期结果
是在不改变整个对象的情况下只更新对象中的某个键值。
PS
我还想更新一个由对象组成的数组,例如上面的对象。
[{a: "text", b: 0}, {c: "another-text", d: 0}]
如果我在 kenxjs 中使用上面的代码,它会将整个数组更新为仅 {b: 1}
PS 经过大量搜索后发现,为了使其工作,我需要将列类型设置为 jsonb,以便上述jsonb_set() 工作
但现在我面临另一个问题
how to update multiple keys using jsonb_set
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1]),
test: knexDb.raw(`jsonb_set(??, '{a}', ?)`, ['test', "another-text"]),
})
第一个查询键 b 现在没有更新,事实上除了最后一个查询键 a
之外所有更新都不起作用,所以有人可以解释为什么吗?
您的问题是您正在覆盖 test
。您传递给 update
的是一个 JS 对象 (docs). You cannot have multiple keys with identical values (docs)。你必须做这样的事情,你用所有原始 SQL 作为 test
.
knexDb('users').where({
email: email
})
.update({
test: knexDb.raw(`
jsonb_set(??, '{a}', ?)
jsonb_set(??, '{b}', ?)
`,
['test', "another-text", 'test', 1])
})
可能存在更好的选择 - 如果您必须对多个列执行此操作,那么可读性会更好,就像我在下面包含的那样。在此示例中,包含 jsonb
的列称为 json
.
const updateUser = async (email, a, b) => {
const user = await knexDb('users')
.where({ email })
.first();
user.json.a = a;
user.json.b = b;
const updatedUser = await knexDb('users')
.where({ email })
.update(user)
.returning('*');
return updatedUser;
}