psql
無法直接讀取文件,除非您打算將其存儲爲大對象,在這種情況下您可以使用lo_import
。請參閱psql
命令\lo_import
。
更新:@AlexandreAlves指出,你可以實際上使用
\set myvar = `cat somefile`
然後引用它作爲一個:'myvar'
可變psql
思樂普文件內容。便利。
雖然它可以讀取文件中使用shell和飼料它psql
這將是笨拙充其量作爲外殼提供既不與參數化查詢的支持,也沒有逃避功能的任何文本的本地PostgreSQL數據庫驅動程序。你將不得不推出自己的字符串轉義。
即使如此,你需要知道輸入文件的文本編碼對你的client_encoding
有效,否則你會插入垃圾和/或獲取錯誤。通過與Python,Perl,Ruby或Java等PostgreSQL的適當集成,它很快就可以輕鬆實現。
有是辦法做你想要在bash如果你真的必須,但:使用PG的delimited dollar quoting用隨機分隔符,以幫助防止SQL注入攻擊。這並不完美,但它非常貼心。我現在正在寫一個例子。
鑑於問題的文件:
$ cat > difficult.txt <__END__
Shell metacharacters like: $!(){}*?"'
SQL-significant characters like "'()
__END__
和樣表:
psql -c 'CREATE TABLE testfile(filecontent text not null);'
您可以:
#!/bin/bash
filetoread=$1
sep=$(printf '%04x%04x\n' $RANDOM $RANDOM)
psql <<__END__
INSERT INTO testfile(filecontent) VALUES (
\$x${sep}\$$(cat ${filetoread})\$x${sep}\$
);
__END__
這可能是一個有點難以閱讀和隨機字符串生成是bash指定的c,儘管我確定可能有便攜式方法。
生成一個由字母數字字符組成的隨機標記字符串(爲方便起見,我使用了十六進制),並將其存儲在seq
中。
psql
然後用一個沒有引用的here-document標籤來調用。缺少引用是很重要的,因爲<<'__END__'
會告知bash
不要解釋字符串中的shell元字符,而只有簡單的<<__END__
才允許shell解釋它們。我們需要shell來解釋元字符,因爲我們需要將sep
替換爲here文檔,並且還需要使用$(...)
(相當於反引號)來插入文件文本。在seq
的每個替換之前的x
是有的,因爲here-document標記必須是有效的PostgreSQL標識符,因此它們必須以字母而不是數字開頭。每個標籤的開頭和結尾處都有一個美元符號,因爲PostgreSQL美元報價格式爲$taghere$quoted text$taghere$
。
所以當腳本調用爲bash testscript.sh difficult.txt
here文檔的土地高達擴大到類似:
INSERT INTO testfile(filecontent) VALUES (
$x0a305c82$Shell metacharacters like: $!(){}*?"'
SQL-significant characters like "'()$x0a305c82$
);
在標籤每一次變化,使得SQL注入的攻擊依賴於過早地結束報價困難。
我仍然建議你使用真正的腳本語言,但這表明它確實有可能。
很好,謝謝。我不知道'\ set'中'psql'支持的反引號命令調用。這很方便,儘管我重複了我的建議,不再試圖在shell和使用本機PostgreSQL綁定的腳本語言中執行此操作。 – 2013-03-25 10:20:49
哦,如果你堅持要用shell做所有事情,你可能遲早會需要協處理器。請參閱http://stackoverflow.com/q/7942632/398670 – 2013-03-25 10:23:29
希望不是,我只需要將數據從基於文本文件的站點遷移到基於PGSQL的站點。 一切完成後,我只需備份數據庫。 :) 但謝謝你的鏈接。 – 2013-03-25 11:15:34