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

时间:2010-06-07 06:19:33

标签: postgresql csv postgresql-copy

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

20 个答案:

答案 0 :(得分:714)

看看这个short article


解决方案在这里解释:

创建表格

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);

答案 1 :(得分:170)

如果您无权使用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);

将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

答案 2 :(得分:65)

这样做的一个简单方法是使用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]

答案 3 :(得分:28)

你也可以使用pgAdmin,它提供了一个GUI来进行导入。这显示在SO thread中。使用pgAdmin的优点是它也适用于远程数据库。

与之前的解决方案非常相似,您需要将数据库放在数据库中。每个人都有自己的解决方案,但我通常做的是在Excel中打开CSV,复制标题,在不同的工作表上粘贴特殊的转置,将相应的数据类型放在下一列,然后将其复制并粘贴到文本编辑器与适当的SQL表创建查询一起如下:

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

答案 4 :(得分:20)

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

右键点击表格 - >进口

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

这是德国pgAdmin GUI截图:

pgAdmin import GUI

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

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

DbVisualizer import GUI

答案 5 :(得分:17)

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

提供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
    set schema 'your-schema';

    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;

答案 6 :(得分:16)

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

答案 7 :(得分:7)

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文件。

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

enter image description here

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

答案 8 :(得分:7)

  1. 首先创建一个表

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

  3. 复制 table_name(C1,C2,C3 ....)
    '路径到你的csv文件'delimiter','csv header;

    由于

答案 9 :(得分:6)

使用此SQL代码

    copy table_name(atribute1,attribute2,attribute3...)
    from 'E:\test.csv' delimiter ',' csv header

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

更多访问http://www.postgresqltutorial.com/import-csv-file-into-posgresql-table/

答案 10 :(得分:5)

恕我直言,最方便的方法是使用Import CSV data into postgresql, the comfortable way ;-)中的csvsql来关注“csvkit”,这是一个可以通过pip安装的python包。

答案 11 :(得分:3)

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

对我有用...

steps:

1=>Need to connect postgresql database in terminal
command : psql -U postgres -h localhost

2=>Need to create database
command : create database mydb;

3=>Need to create user
command : create user siva with password 'mypass';

4=>Connect with database
command : \c mydb;

5=>Need to create schema
command :create schema trip;

6=>Need to create table
command :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=>Import csv file data to postgresql
command: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=>Find the given table data
command : select * from trip.test;

答案 12 :(得分: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 Demo

答案 13 :(得分:1)

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

pgfutter有很多问题,我建议pgcsv。

以下是使用pgcsv的方法:

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

答案 14 :(得分:1)

DBeaver社区版(dbeaver.io)使得连接数据库变得很简单,然后导入CSV文件以上传到PostgreSQL数据库。它还使发布查询,检索数据以及将结果集下载为CSV,JSON,SQL或其他常见数据格式变得容易。

这是一个FOSS多平台数据库工具,适用于SQL程序员,DBA和分析人员,支持所有流行的数据库:MySQL,PostgreSQL,SQLite,Oracle,DB2,SQL Server,Sybase,MS Access,Teradata,Firebird,Hive,Presto等等。它是TOAD for Postgres,TOAD for SQL Server或Toad for Oracle的可行FOSS竞争对手。

我与DBeaver没有任何隶属关系。我喜欢这个价格(免费!)和功能齐全,但是我希望他们能更多地打开这个DBeaver / Eclipse应用程序,并轻松地向DBeaver / Eclipse中添加分析小部件,而不是要求用户仅支付199美元的年度订阅费用直接在应用程序内创建图形和图表。

我的Java编码技能很生疏,而且我不想花数周的时间重新学习如何构建Eclipse小部件,(只是发现DBeaver可能已禁用向DBeaver Community Edition添加第三方小部件的功能。)

作为Java开发人员的DBeaver高级用户能否提供一些有关创建分析小部件以添加到DBeaver社区版的步骤的见解?

答案 15 :(得分:1)

您可以将bash文件创建为import.sh(您的CSV格式是制表符分隔符)

#!/usr/bin/env bash

USER="test"
DB="postgres"
TBALE_NAME="user"
CSV_DIR="$(pwd)/csv"
FILE_NAME="user.txt"

echo $(psql -d $DB -U $USER  -c "\copy $TBALE_NAME from '$CSV_DIR/$FILE_NAME' DELIMITER E'\t' csv" 2>&1 |tee /dev/tty)

然后运行此脚本。

答案 16 :(得分:1)

如果文件非常大,您可以使用pandas 库。 在 Pandas 数据帧上使用 iter 时要小心。我在这里这样做是为了证明这种可能性。从数据帧复制到 sql 表时,也可以考虑 pd.Dataframe.to_sql() 函数

假设你已经创建了你想要的表,你可以:

import psycopg2
import pandas as pd
data=pd.read_csv(r'path\to\file.csv', delimiter=' ')

#prepare your data and keep only relevant columns

data.drop(['col2', 'col4','col5'], axis=1, inplace=True)
data.dropna(inplace=True)
print(data.iloc[:3])


conn=psycopg2.connect("dbname=db user=postgres password=password")
cur=conn.cursor()

for index,row in data.iterrows():
      cur.execute('''insert into table (col1,col3,col6) 
    VALUES (%s,%s,%s)''', (row['col1'], row['col3'], row['col6'])
        
cur.close()
conn.commit()

conn.close()
print('\n db connection closed.')

答案 17 :(得分:0)

创建表并具有用于在csv文件中创建表的必需列。

  1. 打开postgres并右键单击要加载的目标表&amp;选择导入并更新文件选项部分

  2. 中的以下步骤
  3. 现在以文件名

  4. 浏览您的文件
  5. 以格式

  6. 选择csv
  7. 编码为ISO_8859_5

  8. 现在转到其他。选项并检查标题并单击导入。

答案 18 :(得分:0)

在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万行。

答案 19 :(得分:0)

我创建了一个小工具,可以轻松地将csv文件导入到PostgreSQL中,只需一个命令,它将创建并填充表,不幸的是,此刻自动创建的所有字段都使用TEXT

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

该工具可以在https://github.com/eduardonunesp/csv2pg

上找到