sourcecode

CSV 파일에서 Postgre로 복사하는 방법CSV 파일에 헤더가 있는 SQL 테이블?

copyscript 2023. 5. 9. 22:55
반응형

CSV 파일에서 Postgre로 복사하는 방법CSV 파일에 헤더가 있는 SQL 테이블?

CSV 파일을 Postgres 테이블에 복사하려고 합니다.이 표에는 100개 정도의 열이 있기 때문에 굳이 다시 쓰고 싶지 않습니다.

사용 중입니다.\copy table from 'table.csv' delimiter ',' csv;명령이지만 테이블이 생성되지 않으면 얻을 수 있습니다.ERROR: relation "table" does not exist빈 테이블을 추가하면 오류가 발생하지 않지만 아무 일도 일어나지 않습니다.제가 이 명령어를 두세 번 시도했는데 출력이나 메시지가 없었는데 PGAdmin을 통해 확인해보니 테이블이 업데이트되지 않았습니다.

제가 하려고 하는 것처럼 헤더가 포함된 테이블을 가져올 수 있는 방법이 있습니까?

효과가 있었어요.첫 번째 행에는 열 이름이 들어 있습니다.

COPY wheat FROM 'wheat_crop_data.csv' DELIMITER ';' CSV HEADER

Python 라이브러리 사용pandas열 이름을 쉽게 만들고 csv 파일에서 데이터 유형을 추론할 수 있습니다.

from sqlalchemy import create_engine
import pandas as pd

engine = create_engine('postgresql://user:pass@localhost/db_name')
df = pd.read_csv('/path/to/csv_file')
df.to_sql('pandas_db', engine)

if_exists매개 변수를 설정하여 기존 테이블을 대체하거나 추가할 수 있습니다.df.to_sql('pandas_db', engine, if_exists='replace')이것은 추가 입력 파일 형식, 여기여기에 있는 문서에도 적용됩니다.

권한이 없는 터미널별 대안

NOTES의 pg 문서는 다음과 같이 말합니다.

경로는 클라이언트의 작업 디렉토리가 아닌 서버 프로세스의 작업 디렉토리(일반적으로 클러스터의 데이터 디렉토리)에 상대적으로 해석됩니다.

그래서, 일반적으로, 사용.psql또는 로컬 서버에서도 문제가 발생할 수 있습니다.또한 Github README와 같이 다른 사용자를 위해 복사 명령을 표현하는 경우에는 판독기에 문제가 발생합니다.

클라이언트 권한으로 상대 경로를 표현하는 유일한 방법은 STDIN을 사용하는 것입니다.

STDIN 또는 STDOUT가 지정되면 클라이언트와 서버 간의 연결을 통해 데이터가 전송됩니다.

여기서 기억하는 바와 같이:

psql -h remotehost -d remote_mydb -U myuser -c \
   "copy mytable (column1, column2) from STDIN with delimiter as ','" \
   < ./relative_path/file.csv

저는 이 기능을 한동안 문제없이 사용해 왔습니다.csv 파일에 있는 숫자 열을 제공하기만 하면 첫 번째 행의 헤더 이름을 가져와서 테이블을 만들 수 있습니다.

create or replace function data.load_csv_file
    (
        target_table  text, -- name of the table that will be created
        csv_file_path text,
        col_count     integer
    )

    returns void

as $$

declare
    iter      integer; -- dummy integer to iterate columns with
    col       text; -- to keep column names in each iteration
    col_first text; -- first column name, e.g., top left corner on a csv file or spreadsheet

begin
    set schema 'data';

    create table temp_table ();

    -- add just enough number of columns
    for iter in 1..col_count
    loop
        execute format ('alter table temp_table add column col_%s text;', iter);
    end loop;

    -- copy the data from csv file
    execute format ('copy temp_table from %L with delimiter '','' quote ''"'' csv ', csv_file_path);

    iter := 1;
    col_first := (select col_1
                  from temp_table
                  limit 1);

    -- update the column names based on the first row which has the column names
    for col in execute format ('select unnest(string_to_array(trim(temp_table::text, ''()''), '','')) from temp_table where col_1 = %L', col_first)
    loop
        execute format ('alter table temp_table rename column col_%s to %s', iter, col);
        iter := iter + 1;
    end loop;

    -- delete the columns row // using quote_ident or %I does not work here!?
    execute format ('delete from temp_table where %s = %L', col_first, col_first);

    -- change the temp table name to the name given as parameter, if not blank
    if length (target_table) > 0 then
        execute format ('alter table temp_table rename to %I', target_table);
    end if;
end;

$$ language plpgsql;
## csv with header
$ psql -U$db_user -h$db_host -p$db_port -d DB_NAME \
  -c "\COPY TB_NAME FROM 'data_sample.csv' WITH (FORMAT CSV, header);"

## csv without header
$ psql -U$db_user -h$db_host -p$db_port -d DB_NAME \
  -c "\COPY TB_NAME FROM 'data_sample.csv' WITH (FORMAT CSV);"

## csv without header, specify column
$ psql -U$db_user -h$db_host -p$db_port -d DB_NAME \
  -c "\COPY TB_NAME(COL1,COL2) FROM 'data_sample.csv' WITH (FORMAT CSV);"

CSV의 모든 열은 테이블(또는 지정된 열)과 같아야 합니다.


대해서COPY
https://www.postgresql.org/docs/9.2/sql-copy.html

기본 DB 가져오기 명령을 사용하기 때문에 테이블을 만들고 pd.to _sql보다 빠른 d6tstack을 사용할 수 있습니다.Postgres와 MYSQL, MS SQL을 지원합니다.

import pandas as pd
df = pd.read_csv('table.csv')
uri_psql = 'postgresql+psycopg2://usr:pwd@localhost/db'
d6tstack.utils.pd_to_psql(df, uri_psql, 'table')

또한 db에 쓰기 전에 여러 CSV 가져오기, 데이터 스키마 변경 해결 및/또는 팬더 사전 처리(예: 날짜)에도 유용합니다. 아래 예제 노트북을 참조하십시오.

d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv'), 
    apply_after_read=apply_fun).to_psql_combine(uri_psql, 'table')

언급URL : https://stackoverflow.com/questions/17662631/how-to-copy-from-csv-file-to-postgresql-table-with-headers-in-csv-file

반응형