0

I have a Postgres 11.12 database with a table called workflows_emails with a json column called to. The to column has the following format:

[
   {
      "type":"employee",
      "assignment":{
         "..."
      }
   },
   {
      "type":"external",
      "email":"[email protected]"
   }
]

I would like to update the json array to obfuscate the email field in all entities where type field is external. The resulting array would look like:

[
   {
      "type":"employee",
      "assignment":{
         "..."
      }
   },
   {
      "type":"external",
      "email":"[email protected]"
   }
]

Is there a way to do this with a Postgres query?

3
  • Does this answer your question? Search and replace key's value in nested JSON Commented Nov 16, 2022 at 11:34
  • @user3738870 It's very close. Can you show me how to update the query to replace all matching occurrences in a json array? Commented Nov 16, 2022 at 11:44
  • Yes, I've added it as an answer Commented Nov 16, 2022 at 12:28

1 Answer 1

1

Assuming your workflows_emails table has an id primary key column, you can update the appropriate JSON objects in the array by running the following update:

update workflows_emails set "to" = new_to.new_to
from (
    select id,
  json_agg(
    case
      when element ->> 'type' = 'external' then 
             jsonb_set(element, '{email}', to_jsonb(element ->> 'email' || '.SBX'))
      else element
    end
  ) as new_to
from workflows_emails,
     jsonb_array_elements("to") as element
group by id
) new_to
where new_to.id = workflows_emails.id

The subquery in new_to iterates over the elements in the JSON array and transforms the objects where type is external. The iteration is done by unpacking the JSON array with jsonb_array_elements so that we can evaluate a condition and transformation on the individual elements. After the transformation of the appropriate elements, we recreate the JSON array using json_agg. For the transformation, we use jsonb_set, which sets the email field of the existing JSON object to a new value.

The result of the subquery is then used to update the original table's "to" column.

You can see the results on dbfiddle.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow, amazing. Thank you, I learned a lot from reading your solution. I would upvote more if it were possible :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.