CSV 파일 데이터를 PostgreSQL 테이블로 가져 오는 방법은 무엇입니까?


601

CSV 파일에서 데이터를 가져 와서 테이블을 채우는 저장 프로 시저를 작성하려면 어떻게해야합니까?


18
왜 저장 프로 시저입니까? COPY가 트릭을
수행함

1
csv 파일을 업로드하는 사용자 인터페이스가 있는데, 이것을 연결하려면 실제로 cvs 파일에서 데이터를 복사하는 저장 프로 시저가 필요합니다
vardhan

3
복사 사용법에 대해 자세히 설명해 주시겠습니까?
vardhan

17
Bozhidar Batsov는 이미 예제에 대한 링크를 제공했으며 훌륭한 매뉴얼도 도움이 될 수 있습니다. postgresql.org/docs/8.4/interactive/sql-copy.html
Frank Heikens

답변:


774

짧은 기사를 살펴보십시오 .


여기에 솔루션이 해석되었습니다.

테이블을 작성하십시오.

CREATE TABLE zip_codes 
(ZIP char(5), LATITUDE double precision, LONGITUDE double precision, 
CITY varchar, STATE char(2), COUNTY varchar, ZIP_CLASS varchar);

CSV 파일에서 테이블로 데이터를 복사하십시오.

COPY zip_codes FROM '/path/to/csv/ZIP_CODES.txt' WITH (FORMAT csv);

46
실제로 수퍼 유저 액세스 권한이없는 경우 \ copy를 사용하면 동일한 트릭을 수행합니다. 루트가 아닌 계정으로 COPY를 사용할 때 Fedora 16에 불만이 있습니다.
asksw0rder

81
팁 : zip_codes (col1, col2, col3)를 사용하여 CSV에있는 열을 표시 할 수 있습니다. 열은 파일에 나타나는 순서대로 나열되어야합니다.
David Pelaez

6
@ asksw0rder \ copy의 구문이 동일합니까? bcoz \ copy 구문 오류가 발생했습니다
JhovaniC

6
헤더 행을 포함시켜야합니까?
bernie2436

116
헤더 행을 쉽게 포함시킬 수 있습니다. 옵션에 HEADER를 추가하기 만하면됩니다. COPY zip_codes FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV HEADER; postgresql.org/docs/9.1/static/sql-copy.html
Barrett Clark

221

사용 권한이없는 경우 COPY(DB 서버 \copy에서 작동) 대신 (DB 클라이언트에서 작동) 사용할 수 있습니다 . Bozhidar Batsov와 동일한 예를 사용하십시오.

테이블을 작성하십시오.

CREATE TABLE zip_codes 
(ZIP char(5), LATITUDE double precision, LONGITUDE double precision, 
CITY varchar, STATE char(2), COUNTY varchar, ZIP_CLASS varchar);

CSV 파일에서 테이블로 데이터를 복사하십시오.

\copy zip_codes FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV

읽을 열을 지정할 수도 있습니다.

\copy zip_codes(ZIP,CITY,STATE) FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV

COPY 설명서를 참조하십시오 .

COPY를 psql 명령 \ copy와 혼동하지 마십시오. \ copy는 CODY FROM STDIN 또는 COPY TO STDOUT을 호출 한 다음 psql 클라이언트가 액세스 할 수있는 파일로 데이터를 페치 / 저장합니다. 따라서 파일 접근성과 접근 권한은 \ copy가 사용될 때 서버가 아닌 클라이언트에 의존합니다.

참고 :

식별 컬럼의 경우 COPY FROM 명령은 항상 INSERT 옵션 OVERRIDING SYSTEM VALUE와 같이 입력 데이터에 제공된 컬럼 값을 작성합니다.


'/Users/files/Downloads/WOOD.TXT'DELIMITER ','CSV HEADER의 \ copy voters (ZIP, CITY); 오류 : 마지막 예상 열 이후의 추가 데이터 컨텍스트 : COPY 유권자, 2 행 : "OH0012781511,87,26953, HOUSEHOLDER, SHERRY, LEIGH ,, 11 / 26 / 1965,08 / 19 / 1988,, 211 N GARFIELD ST,, BLOOMD ... "
JZ.

@JZ. 비슷한 오류가 발생했습니다. 여분의 빈 열이 있었기 때문입니다. CSV를 확인하고 빈 열이 있으면 그 이유가 있습니다.
alex bennett

5
차이점이 다소 오해의 소지가있다 COPY그리고 \copy더 많은 단지 권한보다, 당신은 단순히``을 만드는 마술 작업을 추가 할 수 없습니다. 여기에서 설명 (내보내기 컨텍스트)을 참조하십시오 : stackoverflow.com/a/1517692/157957
IMSoP

@IMSoP : 당신 말이 맞습니다. 서버와 클라이언트에 대한 언급을 추가했습니다
bjelli

@bjelli는 \ copy가 복사보다 속도가 느립니까? RDS에 1.5MB 파일과 db.m4.large 인스턴스가 있으며이 복사 명령이 실행 된 시간 (최소 3)입니다.
Sebastian

79

이를 수행하는 빠른 방법 중 하나는 Python pandas 라이브러리를 사용하는 것입니다 (버전 0.15 이상이 가장 효과적 임). 이것은 데이터 유형에 대한 선택이 원하는 것이 아닐 수도 있지만 열 생성을 처리합니다. 원하는 것을 수행하지 않으면 항상 템플릿으로 생성 된 '테이블 만들기'코드를 사용할 수 있습니다.

다음은 간단한 예입니다.

import pandas as pd
df = pd.read_csv('mypath.csv')
df.columns = [c.lower() for c in df.columns] #postgres doesn't like capitals or spaces

from sqlalchemy import create_engine
engine = create_engine('postgresql://username:password@localhost:5432/dbname')

df.to_sql("my_table_name", engine)

다음은 다양한 옵션을 설정하는 방법을 보여주는 코드입니다.

# Set it so the raw sql output is logged
import logging
logging.basicConfig()
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)

df.to_sql("my_table_name2", 
          engine, 
          if_exists="append",  #options are ‘fail’, ‘replace’, ‘append’, default ‘fail’
          index=False, #Do not output the index of the dataframe
          dtype={'col1': sqlalchemy.types.NUMERIC,
                 'col2': sqlalchemy.types.String}) #Datatypes should be [sqlalchemy types][1]

6
또한 if_exists기존 테이블을 대체하거나 추가하도록 매개 변수를 설정할 수 있습니다. 예 :df.to_sql("fhrs", engine, if_exists='replace')
joelostblom

1
username과 password : Login을 생성하고 DB를 사용자에게 할당해야합니다. pgAdmin을 사용하는 경우 GUI를 사용하여 "로그인 / 그룹 역할"을 작성하십시오.
Somnath Kadam

9
Pandas는 SQL (vs csv 파일)에로드하는 매우 느린 방법입니다. 훨씬 느릴 수 있습니다.
user48956

이것은 데이터를 작성하는 방법 일 수 있지만 배치 및 우수한 컴퓨팅 성능으로도 매우 느립니다. CSV를 사용하는 것이 좋은 방법입니다.
Ankit Singh

df.to_sql()아주 천천히, 당신은 사용할 수 있습니다 d6tstack.utils.pd_to_psql()에서 d6tstack의 참조 성능 비교
citynorman

30

가져 오기를 수행하는 GUI를 제공하는 pgAdmin을 사용할 수도 있습니다. 이 SO 스레드에 표시 됩니다. pgAdmin을 사용하면 원격 데이터베이스에서도 작동한다는 장점이 있습니다.

그러나 이전 솔루션과 마찬가지로 데이터베이스에 이미 테이블이 있어야합니다. 각 사람은 자신의 솔루션을 가지고 있지만 일반적으로 Excel에서 CSV를 열고 헤더를 복사하고 다른 워크 시트에 조옮김으로 붙여 넣은 다음 해당 열에 해당 데이터 유형을 복사하고 텍스트 편집기에 붙여 넣습니다. 적절한 SQL 테이블 작성 쿼리와 함께 다음과 같이하십시오.

CREATE TABLE my_table (
    /*paste data from Excel here for example ... */
    col_1 bigint,
    col_2 bigint,
    /* ... */
    col_n bigint 
)

1
pls는 붙여 넣은 데이터의 몇 가지 샘플 행을 보여줍니다
dcorking

29

여기에있는 대부분의 다른 솔루션에서는 테이블을 미리 / 수동으로 만들어야합니다. 경우에 따라 실용적이지 않을 수 있습니다 (예 : 대상 테이블에 많은 열이있는 경우). 따라서 아래 접근 방식이 유용 할 수 있습니다.

csv 파일의 경로 및 열 수를 제공하면 다음 함수를 사용하여 테이블을 임시 테이블에 다음과 같이 이름을 지정할 수 있습니다 target_table.

맨 윗줄에는 열 이름이 있다고 가정합니다.

create or replace function data.load_csv_file
(
    target_table text,
    csv_path text,
    col_count integer
)

returns void as $$

declare

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

begin
    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_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
    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;

1
존재하지 않는 스키마 "데이터"안녕 메 흐멧는 답변을 주셔서 감사합니다 당신은 게시하지만 난 당신의 코드를 실행할 때 다음과 같은 오류 메시지가 : 오류를
user2867432을

user2867432 당신은 당신이 따라 (예를 들어, 사용하는 것이 변화의 스키마 이름에 필요 public)
메 흐멧

안녕하세요 Mehmet, 솔루션 주셔서 감사합니다, 그것은 완벽하지만 이것은 postgres DB 사용자가 수퍼 유저 인 경우에만 작동합니다.
Geeme

Geeme : "security definer"를 읽으 십시오 . 그러나 나는 그것을 직접 사용하지 않았습니다.
mehmet

아름다운 답변! 내 코드에서는 다른 사람들이 읽을 수 있도록 너무 일반적이지 않습니다.
Manohar Reddy Poreddy

19

Paul이 언급했듯이 가져 오기는 pgAdmin에서 작동합니다.

테이블을 마우스 오른쪽 버튼으로 클릭-> 가져 오기

로컬 파일, 형식 및 코딩을 선택하십시오.

다음은 독일어 pgAdmin GUI 스크린 샷입니다.

pgAdmin 가져 오기 GUI

DbVisualizer로 할 수있는 비슷한 일 (라이센스가 있지만 무료 버전에 대해서는 확실하지 않습니다)

테이블을 마우스 오른쪽 버튼으로 클릭-> 테이블 데이터 가져 오기 ...

DbVisualizer 가져 오기 GUI


2
DBVisualizer는 3 개의 필드가있는 1400 개의 행을 가져 오는 데 50 초가 걸렸습니다. 모든 것을 String에서 원래의 것으로 캐스트해야했습니다.
Noumenon

19
COPY table_name FROM 'path/to/data.csv' DELIMITER ',' CSV HEADER;

10
  1. 먼저 테이블을 만들

  2. 그런 다음 copy 명령을 사용하여 테이블 세부 사항을 복사하십시오.

'경로에서 CSV 파일 경로로'구분자 ','csv 헤더
에서 table_name (C1, C2, C3 ....) 복사 ;

감사


3
이것이 어떻게 받아 들여지지 않습니까? 데이터베이스에 이미이 명령이있을 때 왜 파이썬 스크립트를 작성합니까?
Wes


8

PostgreSQL에 대한 개인적인 경험으로 여전히 더 빠른 길을 기다리고 있습니다.

1. 파일이 로컬로 저장된 경우 먼저 테이블 스켈레톤을 작성하십시오.

    drop table if exists ur_table;
    CREATE TABLE ur_table
    (
        id serial NOT NULL,
        log_id numeric, 
        proc_code numeric,
        date timestamp,
        qty int,
        name varchar,
        price money
    );
    COPY 
        ur_table(id, log_id, proc_code, date, qty, name, price)
    FROM '\path\xxx.csv' DELIMITER ',' CSV HEADER;

2. \ path \ xxx.csv가 서버에있는 경우 postgreSQL에 서버 액세스 권한이 없으면 pgAdmin 내장 기능을 통해 .csv 파일을 가져와야합니다.

테이블 이름을 마우스 오른쪽 버튼으로 클릭하고 가져 오기를 선택하십시오.

여기에 이미지 설명을 입력하십시오

여전히 문제가있는 경우이 자습서를 참조하십시오. http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/


6

CSV 파일 데이터를 PostgreSQL 테이블로 가져 오는 방법은 무엇입니까?

단계 :

  1. 터미널에서 postgresql 데이터베이스를 연결해야합니다

    psql -U postgres -h localhost
  2. 데이터베이스를 만들어야 함

    create database mydb;
  3. 사용자를 생성해야 함

    create user siva with password 'mypass';
  4. 데이터베이스와 연결

    \c mydb;
  5. 스키마를 만들어야합니다

    create schema trip;
  6. 테이블을 만들어야 함

    create table trip.test(VendorID int,passenger_count int,trip_distance decimal,RatecodeID int,store_and_fwd_flag varchar,PULocationID int,DOLocationID int,payment_type decimal,fare_amount decimal,extra decimal,mta_tax decimal,tip_amount decimal,tolls_amount int,improvement_surcharge decimal,total_amount
    );
  7. PostgreSQL로 CSV 파일 데이터 가져 오기

    COPY trip.test(VendorID int,passenger_count int,trip_distance decimal,RatecodeID int,store_and_fwd_flag varchar,PULocationID int,DOLocationID int,payment_type decimal,fare_amount decimal,extra decimal,mta_tax decimal,tip_amount decimal,tolls_amount int,improvement_surcharge decimal,total_amount) FROM '/home/Documents/trip.csv' DELIMITER ',' CSV HEADER;
  8. 주어진 테이블 데이터 찾기

    select * from trip.test;

5

IMHO에서 가장 편리한 방법은 pip를 통해 설치할 수있는 python 패키지 인 csvkit의 csvsql 을 사용하여 " CSV 데이터를 편안한 방법으로 postgresql로 가져 오기 ;-) "를 따르는 것 입니다.


3
링크 썩음은 엄청납니다! 귀하가 링크 한 기사가 더 이상 작동하지 않아 불편합니다 :(
chbrown

당신은 그의 파이라고 말할 수 있습니다.
mountainclimber

1
나에게 큰 CSV를 가져 오려고하면 MemoryError가 발생하여 스트리밍되지 않는 것처럼 보입니다.
DavidC

@DavidC 흥미로운. 파일이 얼마나 큽니까? 당신은 얼마나 많은 메모리를 가지고 있습니까? 그것이 보여지는대로 스트리밍되지 않는다면, 삽입하기 전에 데이터를 청킹하는 것이 좋습니다
sal

1
파일 크기는 5GB이고 메모리는 2GB입니다. 나는 그것을 포기하고 결국 CREATE TABLE 및 COPY 명령을 생성하는 스크립트를 사용합니다.
DavidC

3

Python에서는이 코드를 열 이름으로 자동 PostgreSQL 테이블 생성에 사용할 수 있습니다.

import pandas, csv

from io import StringIO
from sqlalchemy import create_engine

def psql_insert_copy(table, conn, keys, data_iter):
    dbapi_conn = conn.connection
    with dbapi_conn.cursor() as cur:
        s_buf = StringIO()
        writer = csv.writer(s_buf)
        writer.writerows(data_iter)
        s_buf.seek(0)
        columns = ', '.join('"{}"'.format(k) for k in keys)
        if table.schema:
            table_name = '{}.{}'.format(table.schema, table.name)
        else:
            table_name = table.name
        sql = 'COPY {} ({}) FROM STDIN WITH CSV'.format(table_name, columns)
        cur.copy_expert(sql=sql, file=s_buf)

engine = create_engine('postgresql://user:password@localhost:5432/my_db')

df = pandas.read_csv("my.csv")
df.to_sql('my_table', engine, schema='my_schema', method=psql_insert_copy)

또한 비교적 빠르며 약 4 분 안에 330 만 개 이상의 행을 가져올 수 있습니다.


2

당신은 또한 사용할 수 있습니다 pgfutter을 , 더 나은, 또는 pgcsv을 .

pgfutter는 매우 버그가 많으므로 pgcsv를 권장합니다.

pgcsv로 작업하는 방법은 다음과 같습니다.

sudo pip install pgcsv
pgcsv --db 'postgresql://localhost/postgres?user=postgres&password=...' my_table my_file.csv

1

텍스트 / 구문 분석 여러 줄 CSV에서 가져 오는 간단한 메커니즘이 필요한 경우 다음을 사용할 수 있습니다.

CREATE TABLE t   -- OR INSERT INTO tab(col_names)
AS
SELECT
   t.f[1] AS col1
  ,t.f[2]::int AS col2
  ,t.f[3]::date AS col3
  ,t.f[4] AS col4
FROM (
  SELECT regexp_split_to_array(l, ',') AS f
  FROM regexp_split_to_table(
$$a,1,2016-01-01,bbb
c,2,2018-01-01,ddd
e,3,2019-01-01,eee$$, '\n') AS l) t;

DBFiddle 데모


1

DBeaver Community Edition (dbeaver.io)을 사용하면 데이터베이스에 연결 한 다음 PostgreSQL 데이터베이스에 업로드 할 CSV 파일을 가져올 수 있습니다. 또한 쿼리를 발행하고 데이터를 검색하며 결과 세트를 CSV, JSON, SQL 또는 기타 공통 데이터 형식으로 쉽게 다운로드 할 수 있습니다.

MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Hive, Presto 등 모든 인기있는 데이터베이스를 지원하는 SQL 프로그래머, DBA 및 분석가를위한 FOSS 다중 플랫폼 데이터베이스 도구입니다. Postgres 용 TOAD, SQL Server 용 TOAD 또는 Toad for Oracle의 실행 가능한 FOSS 경쟁 업체입니다.

DBeaver와 제휴 관계가 없습니다. 나는 가격 (무료!)과 모든 기능을 좋아하지만이 DBeaver / Eclipse 애플리케이션을 더 많이 열고 사용자가 연간 $ 199의 연간 구독료를 지불하지 않고 DBeaver / Eclipse에 분석 위젯을 쉽게 추가 할 수 있기를 바랍니다. 응용 프로그램 내에서 직접 그래프와 차트를 만들 수 있습니다. Java 코딩 기술이 녹슬고 Eclipse 위젯을 작성하는 방법을 다시 배우는 데 몇 주가 걸리지 않습니다 .DBeaver가 타사 위젯을 DBeaver Community Edition에 추가하는 기능을 사용하지 못하게 된 것입니다.

Java 개발자 인 DBeaver 고급 사용자는 Community Edition of DBeaver에 추가 할 분석 위젯을 작성하는 단계에 대한 통찰력을 제공 할 수 있습니까?


실제로 DBeaver를 사용하여 CSV 파일을 가져 오는 방법을 이해하면 좋을 것입니다. 어쨌든, 이것은 도움이 될 것입니다 : dbeaver.com/docs/wiki/Data-transfer
umbe1987

0

테이블을 작성하고 csv 파일에서 테이블을 작성하는 데 사용되는 필수 열이 있습니다.

  1. postgres를 열고로드 할 대상 테이블을 마우스 오른쪽 단추로 클릭하고 가져 오기를 선택한 후 파일 옵션 섹션 에서 다음 단계를 업데이트 하십시오.

  2. 이제 파일 이름으로 파일을 찾아보십시오

  3. 형식으로 CSV를 선택하십시오

  4. ISO_8859_5로 인코딩

이제 기타로 이동하십시오. 옵션을 선택 하고 헤더를 확인하고 가져 오기를 클릭하십시오.


0

csvPostgreSQL로 파일을 매우 쉽게 가져 오는 작은 도구를 만들었습니다. 명령 만하면 불행히도 테이블이 자동으로 생성 된 모든 필드가 TEXT 유형을 사용하는 순간 불행히도 테이블을 만들고 채 웁니다.

csv2pg users.csv -d ";" -H 192.168.99.100 -U postgres -B mydatabase

이 도구는 https://github.com/eduardonunesp/csv2pg 에서 찾을 수 있습니다


psql -h 192.168.99.100 -U postgres mydatabase -c "COPY users FROM 'users.csv' DELIMITER ';' CSV"?에 해당하는 별도의 도구를 만들었습니다 . 나는 테이블이 좋은 생성 부분을 생각하지만, 모든 필드가 텍스트이기 때문에 그것은 매우 유용 아니에요
GammaGames

1
Ops, 고맙습니다. 예, 잘했습니다. 단 몇 시간 만에 Go와 pq에서 멋진 것들과 Go에서 데이터베이스 API를 배웠습니다.
Eduardo Pereira
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.