Postgresql

將普通(原始)文件導入 postgres 表(bytea 和大對象)

  • November 25, 2019

將普通文件插入/複製到 postgres 表中的好方法是什麼,最好使用psql命令行?

在我的情況下,這些文件是來自 Maildir 檔案的一堆電子郵件,所以我嘗試使用COPY

psql -c "COPY emails (data) FROM '/tmp/emailfile' WITH (FORMAT text);" emails

我將在 for 循環 shell 腳本 ( for file in $(ls dir); do psql ...; done) 中使用它。

但是,我很難找到一個不可能在文件中的好的“分隔符”,並且我收到了這些錯誤:ERROR: extra data after last expected column.

所以我考慮在數據庫中使用COPY ... FORMAT binary版本和一個BYTEA欄位(然後將列轉換為TEXT數據庫內部),但這需要一個文件頭和拖車,我沒有簡單的方法來即時建構。

有沒有一種簡單的方法可以從命令行執行此操作,還是我需要為此編寫一個 python 腳本?

伺服器端文件

假設帳戶具有pg_read_server_files角色(或者是超級使用者),如果文件可以在伺服器上安裝的文件系統上訪問,並且它們的路徑已收集在表中,這將有效地獲取內容:

UPDATE emails SET mail_data = pg_read_binary_file(emails.fullpath);

它比使用大對像作為中間儲存區域更有效。

客戶端文件

當文件無法在伺服器端訪問或帳戶沒有提升的權限時,對於每個文件,使用 psql 可能是更通用的解決方案:

\set clientpath '/path/to/file'
-- assume clean paths (without any character that would be special to the shell)
\set contents `base64 :clientpath`

insert into email_data([other columns...], mail_data)
values ( [other columns values...], decode(:'contents','base64'));

使用 base64 中間表示,因為 psql 不支持二進制形式的參數。該:'contents'語法指示 psql 將文本形式的變數注入到查詢中。

引用自:https://dba.stackexchange.com/questions/253425