-1

I'm trying to run a Postgres SQL call to migrate data from a jsonb field to separate fields for each attribute, and for some reason the process is not working for the nested fields.

{
  "basis": "relative",
  "defined": "2023-06-21T10:21:16.979",
  "absolute": "2023-06-30T00:00:00.000",
  "relative": {
    "value": 0,
    "period": "month"
  }
}

The SQL being run is:

update gd_task_instance
set 
scheduled_basis = CAST(scheduled->>'basis' AS TEXT),
scheduled_defined = CAST(scheduled->>'defined' as TIMESTAMP),
scheduled_absolute = CAST(scheduled->>'absolute' AS DATE),
scheduled_relative_value = CAST(scheduled->'relative->value' AS INT),
scheduled_relative_period = CAST(scheduled->'relative->>period' AS TEXT);

The last two fields 'scheduled_relative_value' and 'scheduled_relative_period' are not being set.

Any suggestions?

1
  • You meant scheduled -> 'relative' -> 'value' but wrote scheduled -> 'relative->value'. Commented Jan 7 at 7:56

2 Answers 2

1

Replace

'relative->value'
'relative->>period'

with:

'relative' ->> 'value'
'relative' ->> 'period'

Better

UPDATE gd_task_instance
SET    scheduled_basis           =  t.scheduled ->> 'basis'
     , scheduled_defined         = (t.scheduled ->> 'defined')::timestamp
     , scheduled_absolute        = (t.scheduled ->> 'absolute')::date
     , scheduled_relative_value  = (t.scheduled #>> '{relative,value}')::int
     , scheduled_relative_period =  t.scheduled #>> '{relative,period}'
FROM (
   SELECT json
   '{
     "basis": "relative",
     "defined": "2023-06-21T10:21:16.979",
     "absolute": "2023-06-30T00:00:00.000",
     "relative": {
       "value": 0,
       "period": "month"
      }
    }'
   ) t(scheduled)
WHERE  id = 1
RETURNING *
;

fiddle

For two or more nested levels you can shorten the syntax:

t.scheduled -> 'relative' ->> 'period'

... with the #>> operator:

t.scheduled #>> '{relative,period}'

Casting to text is redundant, that's the result type already.

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

2 Comments

One problem I've found is that the nested 'relative.period' attributes are being returned as double quoted strings. How do I get rid of the double quotes?
Note ->> instead of ->. The former returns text, the latter json(b). Consider the added example and fiddle.
0

Found the answer...

update gd_task_instance
set 
scheduled_basis = CAST(scheduled->>'basis' AS TEXT),
scheduled_defined = CAST(scheduled->>'defined' as TIMESTAMP),
scheduled_absolute = CAST(scheduled->>'absolute' AS DATE),
scheduled_relative_value = CAST(scheduled['relative']['value'] AS INT),
scheduled_relative_period = CAST(scheduled['relative']['period'] AS TEXT);

Comments

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.