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

How to import CSV file data into a PostgreSQL table?

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


看看这篇短文。

此处解释的解决方案:

创建表:

1
2
3
CREATE TABLE zip_codes
(ZIP CHAR(5), LATITUDE DOUBLE PRECISION, LONGITUDE DOUBLE PRECISION,
CITY VARCHAR, STATE CHAR(2), COUNTY VARCHAR, ZIP_CLASS VARCHAR);

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

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


如果您没有使用EDOCX1(在数据库服务器上工作)的权限,可以使用EDOCX1(在数据库客户机中工作)。使用与bozhidar batsov相同的示例:

创建表:

1
2
3
CREATE TABLE zip_codes
(ZIP CHAR(5), LATITUDE DOUBLE PRECISION, LONGITUDE DOUBLE PRECISION,
CITY VARCHAR, STATE CHAR(2), COUNTY VARCHAR, ZIP_CLASS VARCHAR);

将数据从csv文件复制到表中:

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

还可以指定要读取的列:

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


一种快速的方法是使用python pandas库(0.15或更高版本最有效)。这将处理为您创建列的问题——尽管很明显,它为数据类型所做的选择可能不是您想要的。如果它不能完全满足您的需要,您可以始终使用作为模板生成的"创建表"代码。

下面是一个简单的例子:

1
2
3
4
5
6
7
8
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)

下面的一些代码向您展示了如何设置各种选项:

1
2
3
4
5
6
7
8
9
10
11
# 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]


您还可以使用pgadmin,它提供了一个GUI来进行导入。在这个so线程中显示的。使用pgadmin的优点是它也适用于远程数据库。

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

1
2
3
4
5
6
7
CREATE TABLE my_table (
    /*paste data from Excel here for example ... */
    col_1 BIGINT,
    col_2 BIGINT,
    /* ... */
    col_n BIGINT
)


正如保罗提到的,导入工作在pgadmin:

右键单击表格->导入

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

以下是德国PGADMIN GUI屏幕截图:

pgAdmin import GUI

使用DBVisualizer也可以做类似的事情(我有一个许可证,不确定免费版本)

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

DbVisualizer import GUI


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

提供csv文件的路径和列计数,可以使用以下函数将表加载到一个名为target_table的临时表中:

假定顶行具有列名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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;


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

个人体验PostgreSQL,还在等待更快的方式。

1。如果文件存储在本地,请首先创建表骨架:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    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。当pathxxx.csv在服务器上时,PostgreSQL没有若要访问服务器,必须通过pgadmin内置功能导入.csv文件。

右键单击表名,选择"导入"。

enter image description here

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


使用此SQL代码

1
2
    copy TABLE_NAME(atribute1,attribute2,attribute3...)
    FROM 'E:\test.csv' delimiter ',' csv header

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

有关更多信息,请访问http://www.postgresqltudio.com/import-csv-file-into-posgresql-table/


imho,最方便的方法是使用csvkit中的csvsql,从csvkit中导入csv数据到postgresql,这是一个可以通过pip安装的python包。


  • 先创建表

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

  • 复制表名(c1,c2,c3….)从'path to your csv file'delimiter'、'csv header;

    谢谢


    如果需要从文本/解析多行csv导入简单机制,可以使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    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$$, '
    '
    ) AS l) t;

    DBFiddle演示


    在python中,可以使用此代码自动创建带有列名的PostgreSQL表:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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万行。


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

  • 打开Postgres,右键单击要加载的目标表,然后选择导入并更新"文件选项"部分中的以下步骤

  • 现在以文件名浏览文件

  • 以格式选择csv

  • 编码为iso__5

  • 现在转到MISC。选项并选中标题,然后单击导入。