PostgreSQL:COPY

Ryan_Bai發表於2020-09-10

COPY 在 PostgreSQL 表和標準檔案系統檔案之間移動資料。COPY TO 將表的內容複製到檔案中,而 COPY FROM 將資料從檔案複製到表中(將資料附加到表中已經存在的任何內容中)。`COPY TO`也可以複製`SELECT`查詢的結果。

如果指定了列表列,則 COPY TO 僅將指定列中的資料複製到檔案中。對於 COPY FROM,按順序將檔案中的每個欄位插入到指定的列中。`COPY FROM`列表列中未指定的表列將接收它們的預設值。

語法

postgres-# \h copy
Command:     COPY
Description: copy data between a file and a table
Syntax:
COPY table_name [ ( column_name [, ...] ) ]
    FROM { 'filename' | PROGRAM 'command' | STDIN }
    [ [ WITH ] ( option [, ...] ) ]
    [ WHERE condition ]
COPY { table_name [ ( column_name [, ...] ) ] | ( query ) }
    TO { 'filename' | PROGRAM 'command' | STDOUT }
    [ [ WITH ] ( option [, ...] ) ]
where option can be one of:
    FORMAT format_name
    FREEZE [ boolean ]
    DELIMITER 'delimiter_character'
    NULL 'null_string'
    HEADER [ boolean ]
    QUOTE 'quote_character'
    ESCAPE 'escape_character'
    FORCE_QUOTE { ( column_name [, ...] ) | * }
    FORCE_NOT_NULL ( column_name [, ...] )
    FORCE_NULL ( column_name [, ...] )
    ENCODING 'encoding_name'
URL: 

引數

  • table_name

    現有表的名稱(可選模式限定)。

  • column_name

    要複製的列的可選列表。如果沒有指定列列表,則將複製表中除生成列之外的所有列。

  • query

    根據 SELECT、VALUES、INSERT、UPDATE 或 DELETE 命令的結果進行復制。注意,查詢周圍需要圓括號。對於 INSERT、UPDATE 和 DELETE 查詢,必須提供一個返回子句,並且目標關係不能有條件規則,也不能有 ALSO 規則,也不能有擴充套件為多個語句的 INSTEAD 規則。

  • filename

    輸入或輸出檔案的路徑名。輸入檔名可以是絕對路徑,也可以是相對路徑,但輸出檔名必須是絕對路徑。Windows 使用者可能需要使用“E”字串,並在路徑名中使用雙斜槓。

  • PROGRAM

    要執行的命令。在`COPY FROM`中,輸入是從命令的標準輸出讀取的,而在`COPY TO`中,輸出被寫入命令的標準輸入。注意,該命令是由 shell 呼叫的,因此,如果需要將來自不可信源的任何引數傳遞給 shell 命令,則必須小心地去掉或轉義任何可能對 shell 有特殊意義的特殊字元。出於安全考慮,最好使用固定的命令字串,或者至少避免在其中傳遞任何使用者輸入。

  • STDIN

    指定輸入來自客戶端應用程式。

  • STDOUT

    指定輸出到客戶端應用程式。

  • boolean

    指定所選選項應該開啟還是關閉。您可以寫`TRUE`、`ON`或`1`來啟用該選項,而寫`FALSE`、`OFF`或`0`來禁用它。也可以省略*`boolean`*值,在這種情況下假定為' TRUE '。

  • FORMAT

    選擇要讀取或寫入的資料格式:`text`、`csv`(逗號分隔值)或`binary`。預設是`text`。

  • FREEZE

    請求使用已經凍結的行復制資料,就像在執行`VACUUM FREEZE` 命令之後所做的那樣。這是用於初始資料載入的效能選項。只有在當前子事務中建立或截斷了正在載入的表,沒有開啟遊標,也沒有該事務持有的舊快照時,才會凍結行。目前無法在分割槽表上執行`COPY FREEZE`。注意,一旦成功載入資料,所有其他會話將立即能夠看到資料。這違反了MVCC可見性的正常規則,使用者在指定時應該意識到這可能會導致的潛在問題。

  • DELIMITER

    指定在檔案的每一行(行)中分隔列的字元。預設是文字格式的製表符,`CSV`格式的逗號。這必須是一個單位元組字元。當使用`binary`格式時,不允許使用此選項。

  • NULL

    指定表示空值的字串。預設是`\N` 的文字格式,以及`CSV`格式的無引號空字串。對於不希望將 null 與空字串區分開的情況,即使是文字格式,您也可能更喜歡使用空字串。當使用`binary` 格式時,不允許使用此選項。當使用`COPY FROM`時,任何與該字串匹配的資料項都將被儲存為空值,因此您應該確保使用與`COPY TO`相同的字串。

  • HEADER

    指定檔案包含一個標題行,其中包含檔案中每個列的名稱。在輸出時,第一行包含表中的列名,而在輸入時,第一行被忽略。只有在使用`CSV`格式時才允許使用此選項。

  • QUOTE

    指定在引用資料值時使用的引用字元。預設是雙引號。這必須是一個單位元組字元。只有在使用`CSV`格式時才允許使用此選項。

  • ESCAPE

    指定應該出現在匹配`QUOTE`值的資料字元之前的字元。預設值與`QUOTE`值相同(因此如果引用字元出現在資料中,它將被加倍)。這必須是一個單位元組字元。只有在使用`CSV`格式時才允許使用此選項。

  • FORCE_QUOTE

    強制引用用於每個指定列中的所有非`NULL`值。`NULL`輸出從不被引用。如果`*`被指定,非`NULL`值將在所有列中引用。此選項只允許在`COPY TO`,並只在使用`CSV`格式。

  • FORCE_NOT_NULL

    不要將指定列的值與空字串匹配。在預設情況下,空字串為 null,這意味著空值將被讀取為零長度的字串,而不是空值,即使它們沒有被引用。此選項只允許在`COPY FROM`中使用,並且只在使用`CSV`格式時使用。

  • FORCE_NULL

    將指定列的值與空字串匹配,即使它已被引用,如果找到匹配,則將值設定為`NULL`。在空字串為空的預設情況下,這將把帶引號的空字串轉換為空字串。此選項只允許在`COPY FROM`中使用,並且只在使用`CSV`格式時使用。

  • ENCODING

    指定檔案編碼在`encoding_name`中。如果省略此選項,則使用當前客戶端編碼。

  • WHERE

    可選的`WHERE` 子句具有一般形式`WHERE *`條件在*`condition`* 是計算結果為`boolean`型別的任何表示式。任何不滿足此條件的行都不會被插入到表中。當實際的行值被替換為任何變數引用時,如果行返回 true,則滿足該條件。目前,子查詢在`WHERE` 表示式中是不允許的,並且計算不會看到`COPY` 本身所做的任何更改(當表示式包含對`VOLATILE` 函式的呼叫時,這一點很重要)。

示例

匯出CSV:

命令

COPY { table_name [ ( column_name [, ...] ) ] | ( query ) }
    TO { 'filename' | PROGRAM 'command' | STDOUT }
    [ [ WITH ] ( option [, ...] ) ]

copy to的匯出速度非常之快,經測試 10W 的資料量只需要 3 秒左右的時間

示例
COPY user TO '/tmp/data/test.csv' WITH csv;

也可以匯出指定的屬性

COPY user(name,password) TO '/tmp/data/test.csv' WITH csv;

也可以使用select 語句

COPY (select * from user) TO '/tmp/data/test.csv' WITH csv;

也可以指定要匯出哪些欄位:

COPY (select name,age from user) TO '/tmp/data/test.csv' WITH csv header;

也可以使用豎線('|')作為欄位分隔符將表複製到客戶端:

COPY country TO STDOUT (DELIMITER '|');

匯入CSV:

命令

COPY table_name [ ( column_name [, ...] ) ]
    FROM { 'filename' | PROGRAM 'command' | STDIN }
    [ [ WITH ] ( option [, ...] ) ]
示例
COPY user_1 FROM '/tmp/data/test.csv' WITH csv;

匯入命令基本與匯出一樣,只是將 TO 改為 FROM

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

COPY user_1(name, age) FROM '/tmp/data/test.csv' WITH csv header;

複製到一個壓縮檔案,你可以透過管道輸出透過一個外部壓縮程式:

COPY country TO PROGRAM 'gzip > /usr1/proj/bray/sql/country_data.gz';

注意

第一點 

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.

普通使用者進行執行,需要在copy前面加入 “\”,即 \copy即可

第二點

如果匯出的欄位,有 integer[] 型別,直接匯出,再匯入的話,會有問題,解決辦法是需要在匯出的時候,進行處理:

COPY ( select coalesce(integer_array, '{}')::integer[] as integer_array from table ) TO '/tmp/data.csv' with csv header;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31490526/viewspace-2718538/,如需轉載,請註明出處,否則將追究法律責任。

相關文章