Команда postgres copy изменяет или заменяет таблицу, в которую я импортирую таблицу? - PullRequest
1 голос
/ 13 июля 2020

Я использую следующий код:

import psycopg2
import pandas as pd
import sys

def pg_load_table(file_path, table_name, dbname, host, port, user, pwd):
    '''
    This function upload csv to a target table
    '''
    try:
        conn = psycopg2.connect(dbname=dbname, host=host, port=port,\
         user=user, password=pwd)
        print("Connecting to Database")
        cur = conn.cursor()
        f = open(file_path, "r")
        # Truncate the table first
        cur.execute("Truncate {} Cascade;".format(table_name))
        print("Truncated {}".format(table_name))
        # Load table from the file with header
        cur.copy_expert("copy {} from STDIN CSV HEADER QUOTE '\"'".format(table_name), f)
        cur.execute("commit;")
        print("Loaded data into {}".format(table_name))
        conn.close()
        print("DB connection closed.")

    except Exception as e:
        print("Error: {}".format(str(e)))
        sys.exit(1)

# Execution Example
file_path = '/tmp/restaurants.csv'
table_name = 'usermanaged.restaurants'
dbname = 'db name'
host = 'host url'
port = '5432'
user = 'username'
pwd = 'password'
pg_load_table(file_path, table_name, dbname, host, port, user, pwd)

Я ожидал, что он добавится к моим данным, но входной файл в итоге заменил мою таблицу. Как я могу отредактировать эту строку:

cur.copy_expert("copy {} from STDIN CSV HEADER QUOTE '\"'".format(table_name), f)

(или больше кода, если необходимо), чтобы команда добавлялась вместо замены? В качестве альтернативы, может ли это поддерживать синтаксис команды update SQL на основе предложения where?

1 Ответ

1 голос
/ 15 июля 2020

Как отмечает Майк Органек в комментариях, эта строка удаляет все данные из вашей таблицы:

cur.execute("Truncate {} Cascade;".format(table_name))

Удалите это, и вы обнаружите, что ваши данные будут добавлены операцией COPY.

Примечание: это означает, что если ваши данные CSV в сочетании с существующими данными в таблице нарушают какие-либо ограничения (скажем, уникальные ключи ...), вся транзакция завершится неудачно, и вы НЕ получите новых данных в своей таблице. Если вам нужно выполнить «Upsert», см .: Как выполнить UPSERT (MERGE, INSERT ... ON DUPLICATE UPDATE) в PostgreSQL?

(FYI: ваш вопрос отмечен как потенциально недопустимый из-за опечатки, но, учитывая явный характер вызова усечения в сочетании с вашим последним абзацем, я подозреваю, что этот logi c был создан, чтобы избежать именно такого нарушения ограничения; COPY лучше всего оставить для массовых загрузок, с большим количеством гибкие подходы, используемые для обновлений.)

...