Xuất bảng Postgres dưới dạng json


35

Có cách nào để xuất dữ liệu bảng postgres thành json vào một tệp không? Tôi cần đầu ra là từng dòng, như:

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

EDIT: phiên bản postgres: 9.3.4

Câu trả lời:


48

Hãy thử ở đây để giới thiệu cơ bản đểPostgreSQLJSON.

Ngoài ra, tài liệu PostgreSQL khá tốt, vì vậy hãy thử ở đây . Kiểm tra các pretty_booltùy chọn.

Câu hỏi ban đầu của bạn là "Có cách nào để xuất dữ liệu bảng postgres thành JSON". Bạn muốn nó ở định dạng này

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

Tôi đã không có một ví dụ chạy PostgreSQL nên tôi đã tải xuống, biên dịch và cài đặt 9.4.

Để trả lời điều này, trước tiên tôi chỉnh sửa CREATEmột bảng (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');

Sau đó, để kiểm tra:

test=# select * from fred;

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

Sau đó tôi đã ban hành lệnh này

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

Sau đó tôi thoát khỏi psql và liệt kê tệp 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]$

(bạn có thể thử nghiệm với đầu ra từ

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

lúc rảnh rỗi).

@ Offby1 đã chỉ ra rằng đầu ra (trong khi tương ứng với câu hỏi của OP) là không chính xác JSON. @EvanCarroll chỉ ra rằng đó \ocũng là một cách xuất ra một tệp, vì vậy tôi đã kết hợp các giải pháp cho hai câu đố này trong tuyên bố này (với sự trợ giúp từ đây ):

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

cho:

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

Cuối cùng , có \vấn đề dấu gạch chéo ngược ( ) được ám chỉ bởi @AdamGent trong bài đăng của anh ấy. Đây là một chút khó khăn, nhưng nó có thể mà không cần đến chế biến sau truy vấn. Võngà:

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

Và bằng cách sử dụng REGEXP_REPLACE, do đó (lưu ý cast :: TEXT) sẽ loại bỏ các dấu gạch chéo thừa.

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

cho:

[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 Như nhận xét của @ Zoltán - đây có thể là một phiên bản - không thể sao chép!).


2
Đó dường như là chính xác những gì các poster ban đầu muốn. Tuy nhiên, lưu ý rằng mặc dù mỗi hàng là JSON thích hợp, nhưng bộ sưu tập các hàng thì không, vì nó thiếu dấu phẩy ngăn cách các hàng và dấu ngoặc vuông bao quanh chúng.
off1

3
Điều này sẽ KHÔNG hoạt động nếu bạn có bất kỳ backslashtrong cột của bạn !!!! Đọc kỹ tài liệu COPY vì nó thực hiện những điều đặc biệt cho các backslashký tự (như thêm dấu gạch chéo ngược khác).
Adam Gent

ĐỌC câu trả lời của @AdamGent bên dưới để giải quyết vấn đề dấu gạch chéo ngược
FacePalm

1
Vậy ... năm 2017 và KHÔNG CÓ CÁCH XUẤT KHẨU JSON bằng lệnh COPY PostgreSQL ?? Có tùy chọn CSV, tùy chọn TXT ... Tại sao không phải là tùy chọn JSON?
Peter Krauss

1
Cảm ơn @ Vérace. Và xin lỗi, bây giờ tôi đã thử nghiệm một BẢN SAO với JSONb phức tạp và JSON được xử lý vẫn ổn, "JSON phù hợp"!
Peter Krauss

13

Nếu bạn đang sử dụng psqlthì không có lý do gì để sử dụng \COPYcả.

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

Đây là phương pháp tương tự mà chúng tôi sử dụng để đưa png / jpgs / tif ra khỏi cơ sở dữ liệu với PostGIS để kiểm tra nhanh và cũng để tạo các tệp tập lệnh có phần mở rộng PostgreQuery.


Tuyệt quá! Như lệnh COPY thông thường "không cho phép đường dẫn tương đối" , các psqllệnh -native là cách dễ nhất để sao chép vào đường dẫn tương đối ! PS: có một "cách cuối" để sử dụng lệnh COPY thực với đường dẫn tương đối, xem tại đây . 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
Peter Krauss

6

Đối với tôi câu trả lời @ Vérace đã không duy trì các tên cột, nhưng tên mặc định được gán ( f1, f2, vv) để thay thế. Tôi đang sử dụng PostgreSQL 9.1 với phần mở rộng JSON .

Nếu bạn muốn xuất toàn bộ bảng, không cần phải có truy vấn con. Ngoài ra, điều này sẽ duy trì tên cột. Tôi đã sử dụng truy vấn folowing:

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

Nó đã duy trì tên cột! CREATE TABLE fred (mary INT, jimmy INT, paulie VARCHAR(20));và kết quả: {"mary":2,"jimmy":43,"paulie":"asfasfasfd"}- tên trường là mary, jimmy, Paulie ... và KHÔNG ( f1, f2., vv) ...
Vérace

5

Tôi sẽ thêm một lời cảnh báo đặc biệt vào câu trả lời của Verace . Bạn cần thực hiện xử lý bài đăng trên tệp JSON được xuất ra nếu bạn có các cột văn bản với các ký tự dấu gạch chéo :\ .

Nếu không, bạn sẽ nhận được bản sao ( \-> \\) tốt nhất và hoàn toàn không hợp lệ JSON ở mức tệ hơn, tức là:

Điều này:

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

Trở thành

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

Có vẻ tốt nhưng JSON hoàn toàn không hợp lệ.

Bạn có thể thay thế \\vào \bằng sed:

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

Từ Postgres COPY nơi họ làm tròn đề cập đến nó:

Hiện tại, COPY TO sẽ không bao giờ phát ra chuỗi dấu gạch chéo bát phân hoặc bát giác, nhưng nó sử dụng các chuỗi khác được liệt kê ở trên cho các ký tự điều khiển đó. Bất kỳ ký tự gạch chéo ngược nào khác không được đề cập trong bảng trên sẽ được lấy để thể hiện chính nó. Tuy nhiên, hãy cẩn thận khi thêm dấu gạch chéo ngược một cách không cần thiết, vì điều đó có thể vô tình tạo ra một chuỗi khớp với điểm đánh dấu cuối dữ liệu (.) Hoặc chuỗi null (\ N theo mặc định). Các chuỗi này sẽ được nhận ra trước khi thực hiện bất kỳ xử lý dấu gạch chéo ngược nào khác.

Chúng tôi đặc biệt khuyến nghị các ứng dụng tạo dữ liệu COPY chuyển đổi dòng dữ liệu mới và vận chuyển trở lại các chuỗi \ n và \ r tương ứng. Hiện tại, có thể biểu thị một sự trở lại vận chuyển dữ liệu bằng một dấu gạch chéo ngược và vận chuyển trở lại, và để thể hiện một dòng mới dữ liệu bằng một dấu gạch chéo ngược và dòng mới. Tuy nhiên, những đại diện này có thể không được chấp nhận trong các phiên bản tương lai. Chúng cũng rất dễ bị hỏng nếu tệp COPY được chuyển qua các máy khác nhau (ví dụ: từ Unix sang Windows hoặc ngược lại).

SAO CHÉP sẽ chấm dứt mỗi hàng với một dòng mới kiểu Unix ("\ n"). Thay vào đó, các máy chủ chạy trên Microsoft Windows thay thế trả về vận chuyển / dòng mới ("\ r \ n"), nhưng chỉ dành cho COPY vào tệp máy chủ; để thống nhất giữa các nền tảng, SAO CHÉP ĐẾN STDOUT luôn gửi "\ n" bất kể nền tảng máy chủ. SAO CHÉP TỪ có thể xử lý các dòng kết thúc bằng dòng mới, trả lại vận chuyển hoặc trả lại / dòng mới. Để giảm nguy cơ lỗi do các dòng mới hoặc trả lại vận chuyển không bị gạch chéo có nghĩa là dữ liệu, SAO CHÉP sẽ khiếu nại nếu các kết thúc dòng trong đầu vào không giống nhau.


Tôi đã giải quyết vấn đề này trong câu trả lời - Tôi hy vọng bạn thấy nó thỏa đáng. Nếu không, hãy cho tôi biết.
Vérace

1

Để biết một giải pháp chung (MySQL, Postgres, SQLite ..) và giải pháp miễn phí mà bạn không phải cài đặt bất kỳ phần mềm nào cho (ngoại trừ Docker), hãy xem https://github.com/feft61/sql2json

Tiết lộ đầy đủ: Tôi đã viết phần mềm đó.


0

Đây là phương thức duy nhất tạo ra JSON (mảng đối tượng) hợp lệ .

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

( nguồn )

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.