web-dev-qa-db-fra.com

Exporter la table Postgres en json

Existe-t-il un moyen d'exporter des données de table PostgreSQL en JSON dans un fichier? J'ai besoin que la sortie soit ligne par ligne, comme:

{'id':1,'name':'David'}
{'id':2,'name':'James'}
...

EDIT: version postgres: 9.3.4

39
AliBZ

Essayez ici pour une introduction de base à PostgreSQL et JSON.

De plus, la documentation PostgreSQL est assez bonne, alors essayez-la ici . Vérifiez pretty_bool option.

Votre question d'origine était "Existe-t-il un moyen d'exporter les données de table PostgreSQL sous la forme JSON". Vous le vouliez dans ce format

{'id':1,'name':'David'}
{'id':2,'name':'James'}
...

Je n'avais pas d'instance en cours d'exécution de PostgreSQL alors j'ai téléchargé, compilé et installé 9.4.

Pour répondre à cela, j'ai d'abord CREATEed une 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');

Ensuite, pour vérifier:

test=# select * from fred;

 mary | jimmy |      paulie      
------+-------+------------------
    2 |    43 | asfasfasfd
    3 |   435 | ererere
    6 | 43343 | eresdfssfsfasfae

Ensuite, j'ai émis cette commande

test=# COPY (SELECT ROW_TO_JSON(t) 
test(# FROM (SELECT * FROM fred) t) 
test-# TO '/paulstuff/sware/db/postgres/inst/myfile';
COPY 3
test=# 

J'ai ensuite quitté psql et répertorié le fichier monfichier.

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]$

(vous pouvez expérimenter avec la sortie de

COPY (SELECT ROW_TO_JSON(t, TRUE)  -- <-- Note addition of "TRUE" here!

à votre guise).

@ Offby1 a fait remarquer que la sortie (tout en correspondant à la question de l'OP) n'est pas correcte JSON. @EvanCarroll a souligné que \o est également un moyen de sortie dans un fichier, j'ai donc combiné les solutions à ces deux problèmes dans cette déclaration (avec l'aide de ici ):

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

donne:

[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]$ 

[~ # ~] enfin [~ # ~] , il y a la barre oblique inverse (\) problème évoqué par @AdamGent dans son message. C'était un peu délicat, mais c'est possible sans avoir recours au traitement post-requête. Voilà:

INSERT INTO fred VALUES (35, 5, 'wrew\sdfsd');
INSERT INTO fred VALUES (3, 44545, '\sdfs\\\sfs\\gf');

Et l'utilisation de REGEXP_REPLACE ainsi (notez le cast :: TEXT) supprime les barres obliques excessives.

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

donne:

[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. Quant au commentaire de @ Zoltán - il s'agit peut-être d'une version - impossible à reproduire!).

54
Vérace

Si vous utilisez psql, il n'y a aucune raison d'utiliser \COPY du tout.

\t
\a
\o file.json
SELECT row_to_json(r) FROM my_table AS r;

C'est la même méthode que nous utilisons pour extraire png/jpgs/tifs de la base de données avec PostGIS pour des tests rapides, et également pour générer des fichiers de script avec des extensions PostgreSQL.

15
Evan Carroll

Pour moi, la réponse de @ Vérace n'a pas conservé les noms des colonnes, mais a attribué des noms par défaut (f1, f2, etc.) à la place. J'utilise PostgreSQL 9.1 avec extension JSON .

Si vous souhaitez exporter l'intégralité de la table, aucune sous-requête n'est nécessaire. De plus, ceci maintiendra les noms de colonne. J'ai utilisé la requête suivante:

COPY (SELECT row_to_json(t) FROM fred as t) to '/home/pol/Downloads/software/postgres/inst/myfile';
6
Zoltán

J'ajouterai une mise en garde spéciale à réponse de Verace . Vous devez effectuer un post-traitement sur le fichier JSON généré si vous avez des colonnes de texte avec des barres obliques inverses: \.

Sinon, vous obtiendrez un double (\ -> \\) au mieux et JSON complètement invalide au pire c'est à dire:

Cette:

{ "f1" : "crap\""}.

Devient

{ "f1" : "crap\\""}.

Ce qui semble bien mais est complètement invalide JSON.

Vous pouvez remplacer le \\ en \ avec sed:

sed -i -e 's/\\\\/\\/g' PG_OUT_JSON_FILE.json

De Postgres COPY où ils le mentionnent:

Actuellement, COPY TO n'émettra jamais une séquence de barre oblique inversée octale ou hexadécimale, mais il utilise les autres séquences répertoriées ci-dessus pour ces caractères de contrôle. Tout autre caractère barre oblique inverse non mentionné dans le tableau ci-dessus sera considéré comme se représentant lui-même. Cependant, méfiez-vous d'ajouter des barres obliques inverses inutilement, car cela pourrait accidentellement produire une chaîne correspondant au marqueur de fin de données (.) Ou à la chaîne nulle (\ N par défaut). Ces chaînes seront reconnues avant tout autre traitement de barre oblique inverse.

Il est fortement recommandé que les applications générant des données COPY convertissent respectivement les retours à la ligne des données et les retours chariot aux séquences\n et\r. Actuellement, il est possible de représenter un retour de chariot de données par une barre oblique inverse et un retour de chariot, et de représenter une nouvelle ligne de données par une barre oblique inverse et une nouvelle ligne. Cependant, ces représentations pourraient ne pas être acceptées dans les versions futures. Ils sont également très vulnérables à la corruption si le fichier COPY est transféré sur différentes machines (par exemple, d'Unix à Windows ou vice versa).

COPY TO terminera chaque ligne avec une nouvelle ligne de style Unix ("\ n"). Les serveurs fonctionnant sous Microsoft Windows produisent à la place un retour chariot/retour à la ligne ("\ r\n"), mais uniquement pour la copie dans un fichier serveur; pour la cohérence entre les plates-formes, COPY TO STDOUT envoie toujours "\ n" quelle que soit la plate-forme du serveur. COPY FROM peut gérer les lignes se terminant par des retours à la ligne, des retours chariot ou des retours chariot/retours à la ligne. Pour réduire le risque d'erreur due à des retours à la ligne sans barre oblique inverse ou à des retours chariot qui étaient censés être des données, COPY FROM se plaindra si les fins de ligne dans l'entrée ne sont pas toutes identiques.

5
Adam Gent

Il s'agit de la seule méthode qui génère JSON valide (tableau d'objets).

\t
\a
\o data.json
select json_agg(t) FROM (SELECT * from table) t;

( source )

1
Gunar Gessner

Pour une solution générique (MySQL, Postgres, SQLite ..) et gratuite pour laquelle vous n'avez pas besoin d'installer de logiciel (sauf Docker), voir https://github.com/function61/sql2json

Divulgation complète: j'ai écrit ce logiciel.

1
joonas.fi