簡體   English   中英

如何將CSV文件數據導入PostgreSQL表

[英]How to import CSV file data into a PostgreSQL table

如何編寫從 CSV 文件導入數據並填充表的存儲過程?

看看這篇短文


此處轉述的解決方案:

創建你的表:

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

如果您無權使用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 ... 必須寫在一行中並且沒有 ; 在末尾!

您還可以指定要讀取的列:

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

請參閱COPY文檔

不要將 COPY 與 psql 指令 \\copy 混淆。 \\copy 調用 COPY FROM STDIN 或 COPY TO STDOUT,然后在 psql 客戶端可訪問的文件中獲取/存儲數據。 因此,當使用 \\copy 時,文件可訪問性和訪問權限取決於客戶端而不是服務器。

並注意:

對於標識列,COPY FROM 命令將始終寫入輸入數據中提供的列值,例如 INSERT 選項 OVERRIDING SYSTEM VALUE。

一種快速的方法是使用 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]

此處的大多數其他解決方案要求您提前/手動創建表。 在某些情況下這可能不切實際(例如,如果目標表中有很多列)。 因此,下面的方法可能會派上用場。

提供 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;

您還可以使用 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 
)
COPY table_name FROM 'path/to/data.csv' DELIMITER ',' CSV HEADER;

正如保羅所提到的,導入在 pgAdmin 中工作:

右擊表格 -> 導入

選擇本地文件、格式​​和編碼

這是德語 pgAdmin GUI 屏幕截圖:

pgAdmin 導入 GUI

你可以用 DbVisualizer 做類似的事情(我有許可證,不確定免費版本)

右鍵單擊表 -> 導入表數據...

DbVisualizer 導入 GUI

  1. 首先創建一個表

  2. 然后使用 copy 命令復制表的詳細信息:

復制table_name (C1,C2,C3....)
from 'path to your csv file' delimiter ',' csv header;

謝謝

個人使用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/

使用此 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/

如何將 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. 將 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;
  8. 查找給定的表數據

    select * from trip.test;

恕我直言,最方便的方法是遵循“將CSV 數據導入 postgresql,舒適的方法 ;-) ”,使用csvkit 中csvsql ,這是一個可通過 pip 安裝的 python 包。

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

這些工具根據 CSV 標題從您創建表格列。

pgfutter 有很多問題,我推薦 pgcsv。

以下是使用 pgcsv 執行此操作的方法:

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

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

如果文件非常大,您可以使用 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.')

如果您需要從文本/解析多行 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 演示

我創建了一個小工具,將csv文件導入 PostgreSQL 超級簡單,只需一個命令,它將創建和填充表,不幸的是,目前所有自動創建的字段都使用 TEXT 類型

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

該工具可以在https://github.com/eduardonunesp/csv2pg上找到

DBeaver 社區版 (dbeaver.io) 使得連接到數據庫,然后導入 CSV 文件以上傳到 PostgreSQL 數據庫變得微不足道。 它還可以輕松發出查詢、檢索數據和將結果集下載為 CSV、JSON、SQL 或其他常見數據格式。

它是一款面向 SQL 程序員、DBA 和分析師的 FOSS 多平台數據庫工具,支持所有流行數據庫:MySQL、PostgreSQL、SQLite、Oracle、DB2、SQL Server、Sybase、MS Access、Teradata、Firebird、Hive、Presto 等。對於 Postgres 的 TOAD、SQL Server 的 TOAD 或 Oracle 的 Toad,它是一個可行的 FOSS 競爭對手。

我與 DBeaver 沒有任何關系。 我喜歡它的價格(免費!)和完整的功能,但我希望他們能更多地打開這個 DBeaver/Eclipse 應用程序,並且可以輕松地向 DBeaver/Eclipse 添加分析小部件,而不是要求用戶支付 199 美元的年度訂閱費用直接在應用程序中創建圖形和圖表。 我的 Java 編碼技能生疏了,我不想花幾周時間重新學習如何構建 Eclipse 小部件,(才發現 DBeaver 可能禁用了將第三方小部件添加到 DBeaver 社區版的能力。)

作為 Java 開發人員的 DBeaver 高級用戶能否提供一些有關創建分析小部件以添加到 DBeaver 社區版的步驟的見解?

您可以創建一個 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)

然后運行這個腳本。

創建表並具有用於在 csv 文件中創建表的必需列。

  1. 打開 postgres 並右鍵單擊要加載的目標表並選擇導入並更新文件選項部分中的以下步驟

  2. 現在在文件名中瀏覽您的文件

  3. 選擇 csv 格式

  4. 編碼為 ISO_8859_5

現在轉到雜項。 選項並檢查標題,然后單擊導入。

通過使用任何客戶端,我使用了 datagrip,我創建了一個新數據庫,然后在數據庫的默認架構(公共)中,右鍵單擊該數據庫,然后執行

Import Data from file

從該位置選擇 csv 文件,然后選擇

Import File --> Formats as TSV --> ensure each column name of the data csv file contributes to the column name of tables.

導入 .csv 文件

我的想法是將您的 CSV 轉換為 SQL 查詢,希望它可以幫助您。

  1. 打開工具Convert CSV to Insert SQL Online
  2. 在“ Data Source窗格中粘貼或上傳您的 CSV 文件
  3. 滾動到Table Generator面板
  4. 單擊Copy to clipboardDownload

例子:

id,name
1,Roberta
2,Oliver

SQL查詢的輸出:

CREATE TABLE tableName 
(
    id  varchar(300),
    name    varchar(300)
);

INSERT INTO tableName (id,name)
VALUES
    ('1', 'Roberta'),
    ('2', 'Oliver');

您有 3 個選項可以將 CSV 文件導入 PostgreSQL:首先,通過命令行使用 COPY 命令。

在此處輸入圖片說明

其次,使用 pgAdmin 工具的導入/導出。

在此處輸入圖片說明

第三,使用像 Skyvia 這樣的雲解決方案,它從在線位置(如 FTP 源)或雲存儲(如 Google Drive)獲取 CSV 文件。

在此處輸入圖片說明

您可以從這里查看解釋所有這些的文章。

這些是一些很好的答案,但對我來說過於復雜。 我只需要將 CSV 文件加載到 postgreSQL 中,而無需先創建表。

這是我的方式:

圖書館

import pandas as pd
import os
import psycopg2 as pg
from sqlalchemy  import create_engine

使用環境變量獲取密碼

password = os.environ.get('PSW')

創建我們的引擎

engine = create_engine(f"postgresql+psycopg2://postgres:{password}@localhost:5432/postgres")

發動機要求分解:

  • engine = create_engine(dialect+driver://username:password@host:port/database)

分解

  • postgresql+psycopg2 = 方言+驅動
  • postgres = 用戶名
  • password = 來自我的環境變量的密碼。 如果需要,您可以輸入密碼,但不推薦
  • 本地主機 = 主機
  • 5432 =端口
  • postgres = 數據庫

獲取您的 CSV 文件路徑,我不得不使用編碼方面。 為什么可以在這里找到原因

data = pd.read_csv(r"path, encoding= 'unicode_escape')

向 Postgress SQL 發送數據:

data.to_sql('test', engine, if_exists='replace')

分解

  • test = 您希望表成為的表名
  • engine = 上面創建的引擎。 又名我們的聯系
  • if_exsists = 將替換舊表(如果有)。 請謹慎使用。

全部一起:

import pandas as pd
import os
import psycopg2 as pg
from sqlalchemy  import create_engine

password = os.environ.get('PSW')

engine = create_engine(f"postgresql+psycopg2://postgres:{password}@localhost:5432/postgres")

data = pd.read_csv(r"path, encoding= 'unicode_escape')
data.to_sql('test', engine, if_exists='replace')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM