ProgramingTip

Postgres에서 CSV 파일의 값으로 선택한 행을 업데이트하는 방법은 무엇입니까?

bestdevel 2020. 11. 20. 09:19
반응형

Postgres에서 CSV 파일의 값으로 선택한 행을 업데이트하는 방법은 무엇입니까?


Postgres를 사용하고 CSV 파일에서 큰 업데이트 쿼리를 만들고 싶습니다 (id, banana, apple).

사과가 아닌 바나나를 변경하는 업데이트를 실행하고 싶습니다. 각각의 새로운 바나나와 해당 ID는 CSV 파일에 있습니다.

Postgres 사이트를 방문했지만 예제가 나를 죽이고 있습니다.


COPY파일을 임시 스테이징 테이블에 저장하고 거기에서 실제 테이블을 업데이트하십시오. 처럼 :

CREATE TEMP TABLE tmp_x (id int, apple text, banana text); -- but see below

COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);

UPDATE tbl
SET    banana = tmp_x.banana
FROM   tmp_x
WHERE  tbl.id = tmp_x.id;

DROP TABLE tmp_x; -- else it is dropped at end of session automatically

거의 테이블이 업데이트 할 테이블과 정확히 일치하면 다음이 편리 할 수 ​​있습니다.

CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;

제약 조건없이 기존 테이블의 구조와 일치하는 빈 임시 테이블을 만듭니다.

특권

SQL COPY에는이를 위해 수퍼 유저 권한이 필요합니다. ( 설명서 ) :

COPY 파일이나 명령의 이름을 지정하는 것은 서버가 액세스 할 수있는 권한이있는 파일을 읽거나 쓸 수 있기 때문에 데이터베이스 수퍼 유저에게만 허용됩니다.

psql의 메타 명령은 어떤 DB 역할에 대해 작동합니다. 매뉴얼 :\copy

클라이언트 엔드 (클라이언트) 복사를 수행합니다. 이 SQL 명령 을 실행하는 작업 이지만 서버가 지정된 파일을 읽거나 쓰는 대신 psql이 파일을 읽거나 쓰고 서버와 로컬 파일 시스템간에 데이터를 라우팅합니다. 즉, 파일 필요 액세스 가능성 및 권한은 서버가 아닌 로컬 사용자의 권한이며 SQL 수퍼 유저 권한이 있습니다.COPY

테이블의 범위 임시는 one-역할 의 one- 세션 으로 제한 되므로 위의 작업은 동일한 psql의 세션에서 실행되어야합니다.

CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;

bash 명령에서이를 스크립팅하는 경우 단일 psql 호출로 래핑해야합니다 . 처럼 :

echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql

일반적으로 \\psql에서 psql 메타 명령 과 SQL 명령 사이 를 전환 하려면 메타 명령 이 필요 하지만 \copy이 규칙의 예외입니다. 다시 매뉴얼 :

특수 구문 분석 규칙이 \copy메타 명령에 적용 됩니다. 대부분의 다른 메타 명령과 달리 줄의 나머지 부분은 항상의 인수로 배열되고 \copy변수 보간이나 따옴표 확장은 인수에서 수행되지 않습니다.

큰 테이블

가져 오기 테이블이 크면 temp_buffers세션에 일시적으로 증가 하는 비용을 지불 할 수 있습니다 (세션의 첫 번째 항목).

SET temp_buffers = '500MB';  -- example value

임시 테이블에 강화를 추가합니다.

CREATE INDEX tmp_x_id_idx ON tmp_x(id);

ANALYZEautovacuum / auto-analyze에 포함되지 않은 수동으로 실행 하십시오 .

ANALYZE tmp_x;

관련 답변 :


내부로 내부 아래 코드를 시도해 볼 수 있습니다. 입력 파일은 내용을 테이블로 업데이트하려는 csv 파일입니다. 각 행은 쉼표를 기준으로 분할 각 행에 대해 행 [0]은 첫 번째 열 아래의 값이고 행 [1]은 두 번째 열 아래의 값입니다.

    import csv
    import xlrd
    import os
    import psycopg2
    import django
    from yourapp import settings
    django.setup()
    from yourapp import models


    try:
       conn = psycopg2.connect("host=localhost dbname=prodmealsdb 
       user=postgres password=blank")
       cur = conn.cursor()

       filepath = '/path/to/your/data_to_be_updated.csv'
       ext = os.path.splitext(filepath)[-1].lower()
       if (ext == '.csv'): 
          with open(filepath) as csvfile:
          next(csvfile)
          readCSV = csv.reader(csvfile, delimiter=',')
          for row in readCSV:
              print(row[3],row[5])
              cur.execute("UPDATE your_table SET column_to_be_updated = %s where 
              id = %s", (row[5], row[3]))
              conn.commit()
          conn.close()
          cur.close()

    except (Exception, psycopg2.DatabaseError) as error:
    print(error)
    finally:
    if conn is not None:
      conn.close()

참고 URL : https://stackoverflow.com/questions/8910494/how-to-update-selected-rows-with-values-from-a-csv-file-in-postgres

반응형