Вставка действительного 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 в файл и запускаю команду копирования, я получаю:

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\\"}" }  

Работает команда копирования. Но правильно ли ожидать специального лечения для типов данных json потому что afterall выше не является допустимым json.

Ответ 1

Формат массовой загрузки по умолчанию PostgreSQL, text, является разметкой, разделенной вкладкой. Для этого требуется обратная косая черта, потому что они имеют особое значение для (например,) нулевого заполнителя \N.

Наблюдайте за тем, что генерирует PostgreSQL:

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

Это не особый случай для json вообще, это верно для любой строки. Рассмотрим, например, что строка, включая json, может содержать встроенные вкладки. Те, которые должны быть экранированы, чтобы их не рассматривали как другое поле.

Вам нужно будет правильно сгенерировать ваши входные данные. Вместо того, чтобы пытаться использовать специфичный для PostgreSQL формат text, обычно проще использовать format csv и использовать инструмент, который записывает правильный CSV, с тем, что вы сделали для записи при записи.