Как правильно удалить вывод из синтаксиса копирования PostgreSQL с помощью python/psycopg2 copy_expert

#python #json #postgresql #psycopg2

Вопрос:

Я передаю объекты jsonb из таблицы postgres в виде большого application/jsonl http-ответа. Это действительно хорошо работает:

 def stream_json_from_copy_syntax():
    conn = psycopg2.connect(...)
    cur = conn.cursor()
    file = BytesIO()
    cur.copy_expert(
        sql="COPY (select my_jsonb from large_table) TO STDOUT WITH (FORMAT text)",
        file=file
    )
    file.seek(0)
    for line in file.readlines():
        line = unescape(line)
        yield line
 

Все вышесказанное помещается в ответную колбу. Это быстро и занимает очень мало места в памяти.

Поле jsonb изначально правильно экранировано, но, похоже (FORMAT text) , добавляется дополнительное экранирование.

Это превращается My string в json propper "My \ string" , а затем в "My \\ string" . Так что происходит дополнительный побег. На данный момент я справился с этим с помощью:

 def unescape(line):
    return line.replace(b'\\', b'\')
 

Я думаю, что это решает большинство проблем, если не все, но я немного не уверен, есть ли другие вещи, с которыми я не справлялся. (FORMAT text)

Как мне правильно развернуть то, что (FORMAT text) делает? Или есть способ вообще не позволить ему избежать чего-либо, потому что первоначальный побег json работает нормально.

Обратите внимание, что использование (ESCAPE 'escape_character') применимо только к (FORMAT csv) : https://www.postgresql.org/docs/current/sql-copy.html

Ответ №1:

Вы экспортируете данные в формате, который копирует Postgres…ОТ бы понял. Возможно, вам нужен другой формат, например CSV.

Комментарии:

1. Знаете ли вы, существует ли библиотека postgres unescape или, может быть, фактическая кодовая база, которую postgres использует для анализа файлов в текстовом формате, в которой я мог бы переопределить в python? Но да. Возможно, если я переконфигурирую версию CSV. Когда я наивно попробовал это сделать, это дало мне кучу дополнительных цитат, но их, возможно, можно удалить.

2. Вы можете использовать psycopg 3 и получить объекты на Python, а затем отформатировать их так, как вы хотите.