Search code examples
sqljsonpostgresqldatabase-migration

Converting postgres string column to json


I have a user table where I want to convert a string column foo to a json with {"oldfield": < the value of foo in the current row >}, but I can't seem to find the right syntax. I'm directly using the psql command line interface.

This is what I tried:

 ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": "foo"}';

This changes the field to exactly {"oldfield":"foo"}, and not that actual value of the foo column. I've also tried the below combos, all of which fail with a syntax error. Any ideas? Thanks

   ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": foo}';
ERROR:  invalid input syntax for type json
DETAIL:  Token "foo" is invalid.
CONTEXT:  JSON data, line 1: {"oldfield": foo...

 ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": \"foo\"}';
ERROR:  invalid input syntax for type json
DETAIL:  Token "\" is invalid.
CONTEXT:  JSON data, line 1: {"oldfield": \...
ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": 'foo'}';
ERROR:  syntax error at or near "foo"
LINE 1: ...Metadata" SET DATA TYPE json USING '{"oldfield": 'foo...
                                                             ^
ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": `foo`}';
ERROR:  invalid input syntax for type json
DETAIL:  Token "`" is invalid.
CONTEXT:  JSON data, line 1: {"oldfield": `...
 ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": user.foo}';
ERROR:  invalid input syntax for type json
DETAIL:  Token "user" is invalid.
CONTEXT:  JSON data, line 1: {"oldfield": user...
ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": user_schema.user.foo}';
ERROR:  invalid input syntax for type json
DETAIL:  Token "user_schema" is invalid.
CONTEXT:  JSON data, line 1: {"oldfield": user_schema...
ALTER TABLE user_schema.user ALTER COLUMN "foo" SET DATA TYPE json USING '{"oldfield": foo}';
ERROR:  invalid input syntax for type json
DETAIL:  Token "foo" is invalid.

Solution

  • Use the function json_build_object():

    create table my_table(foo text);
    insert into my_table values
        ('first'),
        ('second');
    
    alter table my_table 
        alter column foo set data type json 
        using json_build_object('oldfield', foo);
    
    select *
    from my_table;
    
               foo           
    -------------------------
     {"oldfield" : "first"}
     {"oldfield" : "second"}
    (2 rows)