Postgres copy命令導入導出數據


前言
最近有需要對數據進行遷移的需求,由於postgres性能的關系,單表3000W的數據量查詢起來有一些慢,需要對大表進行切割,拆成若干個子表,涉及到原有數據要遷移到子表的需求。起初的想法是使用存儲過程,使用select insert方式進行,但是數據量大的時候耗時有點久,於是需要想別的辦法,就發現了postgres本身支持的copy命令。

copy命令
COPY在PostgreSQL表和文件之間交換數據。 COPY TO把一個表的所有內容都拷貝到一個文件,而COPY FROM從一個文件里拷貝數據到一個表里(把數據附加到表中已經存在的內容里)。 COPY TO還能拷貝SELECT查詢的結果。

如果聲明了一個字段列表,COPY將只在文件和表之間拷貝已聲明字段的數據。 如果表中有任何不在字段列表里的字段,那么COPY FROM將為那些字段插入缺省值。

帶文件名的COPY指示PostgreSQL服務器直接從文件中讀寫數據。 如果聲明了文件名,那么服務器必須可以訪問該文件,而且文件名必須從服務器的角度聲明。 如果使用了PROGRAM選項,則服務器會從指定的這個程序進行輸入或是寫入該程序作為輸出。 如果使用了STDIN 或STDOUT選項,那么數據將通過客戶端和服務器之間的連接來傳輸。

常用參數說明:

table_name
現存表的名字(可以有模式修飾)

column_name
可選的待拷貝字段列表。如果沒有聲明字段列表,那么將使用所有字段

query
一個必須用圓括弧包圍的SELECT或VALUES命令,其結果將被拷貝

filename
輸入或輸出文件的路徑名。輸入文件名可以是絕對或是相對的路徑,但輸出文件名必須是絕對路徑。 Windows用戶可能需要使用E”字符串和雙反斜線作為路徑名稱

PROGRAM
需執行的程序名。在COPY FROM命令中,輸入是從程序的標准輸出中讀取,而在COPY TO中,命令的輸出會作為程序的標准輸入。

注意,程序一般是在命令行界面下執行,當用戶需要傳遞一些變量給程序時,如果這些變量的來源不是可靠的,用戶必須小心過濾處理那些對命令行界面來說是有特殊意義的字符。 基於安全的原因,最好是使用固定的命令字符串,或者至少是應避免直接使用用戶輸入(應先過濾特殊字符)

STDOUT
聲明輸入將寫入客戶端應用

FORMAT
選擇被讀或者寫的數據格式:text、csv(逗號分隔值),或者binary。 默認是text

導出CSV:
命令:

COPY { table_name [ ( column_name [, ...] ) ] | ( query ) }
TO { 'filename' | PROGRAM 'command' | STDOUT }
[ [ WITH ] ( option [, ...] ) ]
1
2
3
copy to的導出速度非常之快,經測試10W的數據量只需要3秒左右的時間

示例:

COPY user TO '/tmp/data/test.csv' WITH csv;
1
也可以導出指定的屬性:

COPY user(name,password) TO '/tmp/data/test.csv' WITH csv;
1
也可以使用select 語句:

COPY (select * from user) TO '/tmp/data/test.csv' WITH csv;
1
也可以指定要導出哪些字段:

COPY (select name,age from user) TO '/tmp/data/test.csv' WITH csv header;
1
導入CSV:
命令:

COPY table_name [ ( column_name [, ...] ) ]
FROM { 'filename' | PROGRAM 'command' | STDIN }
[ [ WITH ] ( option [, ...] ) ]
1
2
3
示例:

COPY user_1 FROM '/tmp/data/test.csv' WITH csv;
1
導入命令基本與導出一樣,只是將TO 改為 FROM

如果導出的時候,指定了header屬性,那么在導入的時候,也需要指定:

COPY user_1(name, age) FROM '/tmp/data/test.csv' WITH csv header;
1
注意事項:
第一點:
copy命令必須在plsql命令行執行,執行用戶必須為superuser,否則會提示:

ERROR: must be superuser to COPY to or from a file
HINT: Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.
1
2
普通用戶進行執行,需要在copy前面加入 “\”,即 \copy即可

第二點:
如果導出的字段,有integer[]類型,直接導出,再導入的話,會有問題,解決辦法是需要在導出的時候,進行處理:

\COPY ( select coalesce(integer_array, '{}')::integer[] as integer_array from table ) TO '/tmp/data.csv' with csv header;
1
更多詳細信息,可以查看官方文檔:

http://www.postgres.cn/docs/9.3/sql-copy.html
---------------------
作者:wtopps
來源:CSDN
原文:https://blog.csdn.net/wtopps/article/details/79097748
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM