Експорт таблиці Postgres як json


35

Чи можна експортувати дані таблиці postgres у вигляді json у файл? Мені потрібен вихід, щоб бути рядком за рядком, наприклад:

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

EDIT: версія постгресів: 9.3.4

Відповіді:


48

Спробуйте тут основний вступ до PostgreSQLта JSON.

Також документація PostgreSQL є досить хорошою, тому спробуйте її тут . Перевірте pretty_boolваріант.

Ваше первісне запитання було "Чи можна експортувати дані таблиці postgres як JSON". Ви хотіли це в такому форматі

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

У мене не було запущеного екземпляра, PostgreSQLтому я завантажував, компілював та встановлював 9.4.

Щоб відповісти на це, я спершу CREATEредагував таблицю (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');

Потім, щоб перевірити:

test=# select * from fred;

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

Тоді я видав цю команду

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

Потім я закрив psql і перерахував файл 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]$

(Ви можете експериментувати з результатами з

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

у ваше дозвілля).

@ Offby1 вказувало, що вихід (хоча відповідає питанню ОП) невірний JSON. @EvanCarroll зазначав, що \oце також спосіб виведення файлу, тому я поєднав рішення цих двох ніггерів у цьому операторі (за допомогою звідси ):

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

дає:

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

Зрештою , існує \проблема зворотної косої риски ( ), на яку посилається @AdamGent у своєму дописі. Це було трохи складно, але це можливо , не вдаючись до обробки після запиту. Voilà:

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

І, використовуючи REGEXP_REPLACE таким чином (зверніть увагу на роль :: TEXT), видаляйте зайві коси.

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

дає:

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

(ps Що стосується коментаря @ Zoltán - це може бути версія версії - неможливо відтворити!).


2
Це, здається, саме те, чого хотів оригінальний плакат. Однак зауважте, що, хоча кожен рядок є належним JSON, колекція рядків не є, оскільки у ньому відсутні коми, що розділяють рядки, та квадратні дужки, що оточують їх.
offby1

3
Це НЕ буде працювати, якщо у вас є якісь backslashколонки !!!! Уважно прочитайте документ COPY, оскільки він робить спеціальні речі для backslashперсонажів (наприклад, додавання ще однієї косої риски).
Адам Гент

ЧИТАЙТЕ відповідь @AdamGent нижче, щоб вирішити проблему зворотної косої риси
FacePalm

1
Отже ... рік 2017 і НЕ ШЛЯХ ЕКСПОРТУВАТИ JSON за допомогою команди COPY PostgreSQL ?? Є опція CSV, опція TXT ... Чому б не варіант JSON?
Пітер Краус

1
Дякуємо @ Vérace. І вибачте, зараз я перевірив КОПІЮ із комплексом JSONb, і пройдений JSON був чудовим, "правильним JSON"!
Пітер Краусс

13

Якщо ви користуєтеся, psqlто взагалі немає причин використовувати \COPY.

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

Це той самий метод, який ми використовуємо для отримання png / jpgs / tifs з бази даних за допомогою PostGIS для швидких тестів, а також для створення файлів сценаріїв з розширеннями PostgreSQL.


Чудово! Як зазвичай команда COPY "не допускати відносний шлях" , psql-native-команди - це найпростіший спосіб скопіювати у відносний шлях ! PS: Є "термінальний спосіб" використовувати реальну команду COPY з відносним шляхом, дивіться тут . psql -h remotehost -d remote_mydb -U myuser -c "COPY (SELECT '{\"x\":1,\"y\":[\"a\",2]}'::json AS r) TO STDOUT" > ./relative_path/file.csv
Пітер Краусс

6

Для мене @ відповідь Verace в не витримував імена стовпців, але призначені імена по замовчуванням ( f1, f2і т.д.) замість цього. Я використовую PostgreSQL 9.1 з розширенням JSON .

Якщо ви хочете експортувати всю таблицю, немає необхідності в підзапиті. Крім того, це буде підтримувати імена стовпців. Я використовував наступний запит:

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

Він підтримував назви стовпців! CREATE TABLE fred (mary INT, jimmy INT, paulie VARCHAR(20));і результат: {"mary":2,"jimmy":43,"paulie":"asfasfasfd"}- назви полів mary, jimmy, paulie ... і NOT ( f1, f2і т. д.) ...
Vérace

5

Я додам спеціальний застереження до відповіді Верації . Якщо у вас є текстові стовпці із зворотними косою рисою, вам потрібно виконати обробку після виводу на вихідний файл JSON\ .

Інакше ви отримаєте дублікат ( \-> \\) в кращому випадку і повністю недійсний JSON в гіршому випадку, тобто:

Це:

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

Стає

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

Це добре виглядає, але абсолютно недійсне JSON.

Ви можете замінити \\на \sed на:

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

З Postgres COPY, де вони обговорюють про це:

В даний час COPY TO ніколи не випускає восьмеричну або шістнадцяткову послідовність зворотної косої риси, але він використовує інші послідовності, перелічені вище для цих контрольних символів. Будь-який інший відхилений символ, який не згадується у таблиці, буде представлений самим собою. Однак остерігайтеся додавання косої риски без необхідності, оскільки це може випадково створити рядок, що відповідає маркеру кінця даних (.) Або нульовому рядку (за замовчуванням \ N). Ці рядки будуть розпізнані до того, як буде виконана будь-яка інша зворотна косоокість.

Настійно рекомендується, щоб програми, що генерують дані COPY, конвертували дані нових рядків і каретка повертається до послідовностей \ n та \ r відповідно. В даний час можна представляти повернення каретки даних за допомогою зворотної косої лінії та повернення каретки, а також представляти нову лінію даних за допомогою косої та нової лінії. Однак ці подання можуть не бути прийнятими в майбутніх випусках. Вони також дуже вразливі до корупції, якщо файл COPY передається на різних машинах (наприклад, з Unix в Windows або навпаки).

COPY TO завершить кожен рядок новим рядком у стилі Unix ("\ n"). Сервери, що працюють на Microsoft Windows, замість цього виводять каретку return / newline ("\ r \ n"), але лише для COPY у файл сервера; для послідовності на різних платформах, COPY TO STDOUT завжди надсилає "\ n" незалежно від платформи сервера. COPY FROM може обробляти лінії, що закінчуються новими рядками, поверненнями перевезення або поверненнями / новинками каретки. Щоб знизити ризик помилок через невідкладені нові рядки або повернення перевезення, які були позначені як дані, COPY FROM поскаржиться, якщо закінчення рядків у введенні не однакові.


Я розібрався з цим у відповіді - сподіваюся, ви вважаєте його задовільним. Якщо ні, то дайте мені знати.
Vérace

1

Щодо загального (MySQL, Postgres, SQLite ..) та безкоштовного рішення, для якого не потрібно встановлювати жодне програмне забезпечення (крім Docker), див. Https://github.com/function61/sql2json

Повне розкриття: я написав це програмне забезпечення.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.