Export Postgres table as json
Try here for a basic intro to PostgreSQL
and JSON
.
Also, PostgreSQL documentation is pretty good, so try it here. Check out the pretty_bool
option.
Your original question was "Is there a way to export postgres table data as JSON
". You wanted it in this format
{'id':1,'name':'David'}
{'id':2,'name':'James'}
...
I didn't have a running instance of PostgreSQL
so I downloaded, compiled and installed 9.4.
To answer this, I first CREATE
ed a table (fred)
CREATE TABLE fred (mary INT, jimmy INT, paulie VARCHAR(20));
INSERT INTO fred VALUES (2, 43, 'asfasfasfd' );
INSERT INTO fred VALUES (3, 435, 'ererere' );
INSERT INTO fred VALUES (6, 43343, 'eresdfssfsfasfae');
Then, to check:
test=# select * from fred;
mary | jimmy | paulie
------+-------+------------------
2 | 43 | asfasfasfd
3 | 435 | ererere
6 | 43343 | eresdfssfsfasfae
Then I issued this command
test=# COPY (SELECT ROW_TO_JSON(t)
test(# FROM (SELECT * FROM fred) t)
test-# TO '/paulstuff/sware/db/postgres/inst/myfile';
COPY 3
test=#
I then quit psql and listed the file myfile.
test=# \q
[pol@polhost inst]$ more myfile
{"mary":2,"jimmy":43,"paulie":"asfasfasfd"}
{"mary":3,"jimmy":435,"paulie":"ererere"}
{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}
[pol@polhost inst]$
(you can experiment with the output from
COPY (SELECT ROW_TO_JSON(t, TRUE) -- <-- Note addition of "TRUE" here!
at your leisure).
It was pointed out by @offby1 that the output (while corresponding to the OP's question) is not correct JSON
. @EvanCarroll pointed out that \o
is also a way of outputting to a file, so I combined the solutions to these two niggles in this statement (with help from here):
test=# \o out.json
test=# SELECT array_to_json(array_agg(fred), FALSE) AS ok_json FROM fred;
-- <-- "TRUE" here will produce plus
("+) signs in the output. "FALSE"
is the default anyway.
test=# \o
gives:
[pol@polhost inst]$ more out.json
ok_json
----------------------------------------------------------------------------------------------------------------------------------------------
[{"mary":2,"jimmy":43,"paulie":"asfasfasfd"},{"mary":3,"jimmy":435,"paulie":"ererere"},{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}]
(1 row)
[pol@polhost inst]$
FINALLY, there is the backslash (\
) problem alluded to by @AdamGent in his post. This was a bit tricky, but it is possible without resorting to post-query processing. Voilà:
INSERT INTO fred VALUES (35, 5, 'wrew\sdfsd');
INSERT INTO fred VALUES (3, 44545, '\sdfs\\\sfs\\gf');
And using REGEXP_REPLACE thus (note the cast ::TEXT) removes the excess blackslashes.
test=# \o slash.json
test=# SELECT REGEXP_REPLACE(ROW_TO_JSON(t)::TEXT, '\\\\', '\\', 'g')
test=# FROM (SELECT * FROM fred) AS t; -- I found that using a CTE was helpful for legibility
test=# \o
test=# \q
gives:
[pol@polhost inst]$ more slash.json
regexp_replace
------------------------------------------------------
{"mary":2,"jimmy":43,"paulie":"asfasfasfd"}
{"mary":3,"jimmy":435,"paulie":"ererere"}
{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}
{"mary":35,"jimmy":5,"paulie":"wrew\sdfsd"}
{"mary":3,"jimmy":44545,"paulie":"\sdfs\\\sfs\\gf"}
(5 rows)
[pol@polhost inst]$
(p.s. As for @Zoltán 's comment - this may be a version thing - unable to reproduce!).
If you're using psql
then there is no reason to use \COPY
at all.
\t
\a
\o file.json
SELECT row_to_json(r) FROM my_table AS r;
This is the same method we use to get png/jpgs/tifs out of the database with PostGIS for quick tests, and also to generate script files with PostgreSQL extensions.
For me @Vérace's answer didn't maintain the column names, but assigned default names (f1
, f2
, etc.) instead. I am using PostgreSQL 9.1 with the JSON extension.
If you want to export the entire table, there is no need for a subquery. In addition, this will maintain the column names. I used the folowing query:
COPY (SELECT row_to_json(t) FROM fred as t) to '/home/pol/Downloads/software/postgres/inst/myfile';