How to update a key of object with value in json column with knexjs?

做~自己de王妃 提交于 2019-12-24 07:56:34

问题


I'm trying to update a column in users table the column type is json.

column name is test.

and the column consists of an object default value for example is

{a: "text", b: 0}

how to update let's say the object key b without changing the whole column

the code i'm using is

knexDb('users').where({
  email: email
})
.update({
  test: { b: 1 }
})

second solution

knexDb('users').where({
  email: email
})
.update({
  test: knexDb.raw(`jsonb_set(??, '{b}', ?)`, ['test', 1])
})

first solution changes the whole column cell and test will be only { b: 1 }

second solution doesn't work it give an error

function jsonb_set(json, unknown, unknown) does not exist

The expected result

is to manage to update only a certain key value in an object without changing the whole object.

PS

I also want to update an array that consists of objects like the above one for example.

[{a: "text", b: 0}, {c: "another-text", d: 0}]

if i use the code above in kenxjs it'll update the whole array to only {b: 1}

PS after searching a lot found that in order to make it work i need to set column type to jsonb, in order the above jsonb_set() to work

but now i'm facing another issue

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"]),
    })

the first query key b is now not updating, in fact all updates don't work except the last query key a, so can some explain why ?


回答1:


Your issue is that you're overwriting test. What you're passing into update is a JS object (docs). You cannot have multiple keys with identical values (docs). You'll have to do something like this where you make 1 long string with all your raw SQL as the value to test.

knexDb('users').where({
      email: email
    })
    .update({
      test: knexDb.raw(`
          jsonb_set(??, '{a}', ?)
          jsonb_set(??, '{b}', ?)
        `,
        ['test', "another-text", 'test', 1])
    })

Probably a better option exists - one that would be much more readable if you have to do this for several columns is something like what I have included below. In this example, the column containing the jsonb is called 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;
}


来源:https://stackoverflow.com/questions/57331278/how-to-update-a-key-of-object-with-value-in-json-column-with-knexjs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!