如何将CSV文件数据导入PostgreSQL表?

var*_*han 565 csv postgresql postgresql-copy

如何编写从CSV文件导入数据并填充表的存储过程?

Boz*_*sov 741

看看这篇短文.


解决方案在这里解释:

创建你的表:

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

将CSV文件中的数据复制到表格中:

COPY zip_codes FROM '/path/to/csv/ZIP_CODES.txt' WITH (FORMAT csv);
Run Code Online (Sandbox Code Playgroud)

  • 您可以轻松地包含标题行 - 只需在选项中添加HEADER:`COPY zip_codes FROM'/ path/to/ccsv/ZIP_CODES.txt'DELIMITER','CSV HEADER;`http://www.postgresql.org/文档/ 9.1 /静态/ SQL-copy.html (109认同)
  • 提示:您可以使用zip_codes(col1,col2,col3)指示CSV中的列.列必须按它们在文件中出现的顺序列出. (81认同)
  • 如果你没有超级用户访问权限,实际使用\ copy会做同样的技巧; 当使用COPY与非root帐户时,它投诉我的Fedora 16. (43认同)
  • @asksw0rder\copy有相同的语法吗?bcoz我在\ copy中遇到语法错误 (6认同)
  • 我应该包括标题行吗? (6认同)
  • 这会覆盖现有表中的数据,还是附加它? (2认同)

bje*_*lli 183

如果您没有使用权限COPY(在数据库服务器上工作),则可以使用\copy(在数据库客户端中有效).使用与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);
Run Code Online (Sandbox Code Playgroud)

将CSV文件中的数据复制到表格中:

\copy zip_codes FROM '/path/to/csv/ZIP_CODES.txt' DELIMITER ',' CSV
Run Code Online (Sandbox Code Playgroud)

您还可以指定要读取的列:

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

  • 这有点误导:`COPY`和`\ copy`之间的区别不仅仅是权限,你不能简单地添加一个`\`来使它神奇地工作.请在此处查看说明(在导出的上下文中):http://stackoverflow.com/a/1517692/157957 (5认同)
  • @Sebastian:重要的区别是 \copy 从客户端工作。所以你仍然需要将所有数据传输到服务器。使用 COPY(无斜杠),您首先使用其他方式(sftp、scp)将所有数据上传到服务器,然后在服务器上进行导入。但传输 1.5 MB 听起来并不像是需要通话 3 个小时——无论您采用哪种方式。 (3认同)

Rob*_*inL 73

一个快速的方法是使用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)
Run Code Online (Sandbox Code Playgroud)

这里有一些代码向您展示如何设置各种选项:

# 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]
Run Code Online (Sandbox Code Playgroud)

  • Pandas是一种加载到sql(vs csv文件)的超慢速方式.可以慢几个数量级. (9认同)
  • 另外,`if_exists`参数可以设置为替换或附加到现有表,例如`df.to_sql("fhrs",engine,if_exists ='replace')` (6认同)

Pau*_*aul 29

您还可以使用pgAdmin,它提供了一个GUI来进行导入.这在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 
)
Run Code Online (Sandbox Code Playgroud)


meh*_*met 26

此处的大多数其他解决方案都要求您提前/手动创建表.在某些情况下这可能不实用(例如,如果目标表中有很多列).因此,下面的方法可能会派上用场.

提供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;
Run Code Online (Sandbox Code Playgroud)

  • 嗨,Mehmet,感谢您的解决方案,它很完美,但是只有当 postgres DB 用户是超级用户时,这才有效,有没有什么方法可以让它在没有超级用户的情况下工作? (2认同)
  • 漂亮的答案!为了其他人的可读性,我不会在我的代码中过于通用。 (2认同)

And*_* L. 19

正如保罗所说,导入工作在pgAdmin:

右键单击表 - >导入

选择本地文件,格式和编码

这是一个德国pgAdmin GUI截图:

pgAdmin导入GUI

你可以用DbVisualizer做类似的事情(我有许可证,不确定免费版)

右键单击表 - >导入表数据...

DbVisualizer导入GUI

  • DBVisualizer花了50秒来导入1400行,包含三个字段 - 我不得不将所有内容从一个字符串转换回原来的内容. (2认同)

Tim*_*ula 16

COPY table_name FROM 'path/to/data.csv' DELIMITER ',' CSV HEADER;
Run Code Online (Sandbox Code Playgroud)


小智 9

  1. 首先创建一个表

  2. 然后使用copy命令复制表详细信息:


“到csv文件的路径”,“定界符”,“ csv头”中复制 table_name(C1,C2,C3 ....);

谢谢

  • 这怎么不是被接受的答案?当数据库已经有执行此命令的命令时,为什么还要编写python脚本? (3认同)

flo*_*era 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;
Run Code Online (Sandbox Code Playgroud)

2.当\ path\xxx.csv在服务器上时,postgreSQL没有访问服务器的权限,您必须通过内置的pgAdmin功能导入.csv文件.

右键单击表名称选择导入.

在此输入图像描述

如果您仍有问题,请参阅本教程. http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/


Vla*_*scu 8

您还可以使用pgfutter,或者更好的是pgcsv

这些工具根据 CSV 标题为您创建表格列。

pgfutter 有很多 bug,我推荐 pgcsv。

以下是如何使用 pgcsv 执行此操作:

sudo pip install pgcsv
pgcsv --db 'postgresql://localhost/postgres?user=postgres&password=...' my_table my_file.csv
Run Code Online (Sandbox Code Playgroud)


小智 6

使用此SQL代码

    copy table_name(atribute1,attribute2,attribute3...)
    from 'E:\test.csv' delimiter ',' csv header
Run Code Online (Sandbox Code Playgroud)

header关键字让DBMS知道csv文件有一个带属性的头

欲了解更多信息,请访问http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/


Mar*_*arc 6

在 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)
Run Code Online (Sandbox Code Playgroud)

它也相对较快。我可以在大约 4 分钟内导入超过 330 万行。


sal*_*sal 5

恕我直言,最方便的方法是按照" 导入CSV数据于PostgreSQL,舒适的方式;-) ",使用csvsqlcsvkit,这是一个Python包通过PIP安装.

  • 链接腐烂是贪婪的!你链接的文章不再有效,这让我感到不舒服:( (2认同)

小智 5

如何将CSV文件数据导入PostgreSQL表?

脚步:

  1. 需要在终端中连接PostgreSQL数据库

    psql -U postgres -h localhost
    
    Run Code Online (Sandbox Code Playgroud)
  2. 需要创建数据库

    create database mydb;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 需要创建用户

    create user siva with password 'mypass';
    
    Run Code Online (Sandbox Code Playgroud)
  4. 与数据库连接

    \c mydb;
    
    Run Code Online (Sandbox Code Playgroud)
  5. 需要创建架构

    create schema trip;
    
    Run Code Online (Sandbox Code Playgroud)
  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
    );
    
    Run Code Online (Sandbox Code Playgroud)
  7. 将CSV文件数据导入到PostgreSQL

    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;
    
    Run Code Online (Sandbox Code Playgroud)
  8. 查找给定的表数据

    select * from trip.test;
    
    Run Code Online (Sandbox Code Playgroud)