web-dev-qa-db-ja.com

有効なjsonとコピーをpostgresテーブルに挿入する

有効なJSONには、当然、バックスラッシュ文字\を含めることができます。次のようにSQLステートメントにデータを挿入する場合:

sidharth=# create temp table foo(data json);
CREATE TABLE
sidharth=# insert into foo values( '{"foo":"bar", "bam": "{\"mary\": \"had a lamb\"}" }');
INSERT 0 1

sidharth=# select * from foo;

data                         
\-----------------------------------------------------

{"foo":"bar", "bam": "{\"mary\": \"had a lamb\"}" }
(1 row)

物事はうまくいきます。

しかし、JSONをファイルにコピーして、copyコマンドを実行すると、次のようになります。

sidharth=# \copy foo from './tests/foo' (format text); 


ERROR:  invalid input syntax for type json
DETAIL:  Token "mary" is invalid.
CONTEXT:  JSON data, line 1: {"foo":"bar", "bam": "{"mary...
COPY foo, line 1, column data: "{"foo":"bar", "bam": "{"mary": "had a lamb"}" }"

Postgresがバックスラッシュを処理していないようです。 http://www.postgresql.org/docs/8.3/interactive/sql-syntax-lexical.html のせいで、ダブルバックスラッシュを使用せざるを得ないと思います。そして、それは機能します。つまり、ファイルの内容が次の場合です。

{"foo":"bar", "bam": "{\\"mary\\": \\"had a lamb\\"}" }  

Copyコマンドは機能します。しかし、結局のところ上記は有効なjsonではないため、jsonデータ型の特別な扱いを期待するのは正しいですか。

11
Sid

http://adpgtech.blogspot.ru/2014/09/importing-json-data.html

copy the_table(jsonfield) 
from '/path/to/jsondata' 
csv quote e'\x01' delimiter e'\x02';
12
Vlad Purga

PostgreSQLのデフォルトの一括読み込み形式であるtextは、タブ区切りのマークアップです。 \N nullプレースホルダーには特別な意味があるため、バックスラッシュをエスケープする必要があります。

PostgreSQLが生成するものを観察します。

regress=> COPY foo TO stdout;
{"foo":"bar", "bam": "{\\"mary\\": \\"had a lamb\\"}" }

これはjsonの特殊なケースではなく、どの文字列にも当てはまります。たとえば、文字列(jsonを含む)に埋め込みタブが含まれている可能性があることを考慮してください。それらが別のフィールドとして見られるのを防ぐために、それらはエスケープされなければなりません。

適切にエスケープされた入力データを生成する必要があります。通常、PostgreSQL固有のtext形式を使用するよりも、format csvを使用して、正しいCSVを書き込むツールを使用し、書き込み時にエスケープを行う方が簡単です。

6
Craig Ringer