質問: AWSのRDSでpostgresqlを使用しております。 定期的なデータ更新があり、シェルスクリプトとSQLで更新環境を作成しております。 ローカル(vagrantで作成したcentos6)で試していた際はsuperuser権限が使用出来たため、下記の様な書き方で実行しておりました。 ``` \set :inputfile ←シェルから変数で渡しています。 copy hoge from :inputfile (format csv, header true); ``` ですがAWSのRDSだとsuperuserのロールが作れない、もしくは作るのが難しいため、下記のように書き変えました。 ですが「from :inputfile」の「:inputfile」の中のパスが展開の仕方が分からず困っております。 エラー内容も[:inputfile: No such file or directory]でおそらく「:inputfile」が展開されてないのではと思っております。※なぜか「末尾に:がついているのも気になりますが・・・」 ``` \set :inputfile \copy hoge from :inputfile with csv HEADER DELIMITER ','; ``` 自分なりに調べた内容は以下の点です。 ・ファイルのパスを直打ちで'hoge.csv'とすると正常に動作する。 ・「/echo :inputfile」で出力されたパスは表示され catなどで確認しても中身はある。 もう少しで正常に動作させられそうなのですが、どうしてもfrom の部分の書き方が分からず質問致しました。 どなたか答え、もしくはヒントでも良いのでお助け下さい。 お礼と補足: 大変申し訳ございませんが、手元に実行環境が無いため検証できしだい、ベストアンサーを選択致します。 また、質問内容が分かりにくく申し訳ありません。 構成としては、「.sh」でCSV手前までのパスを定義して、そのファイル内でpsqlに接続し、一緒に実行する外部SQLファイル、変数を渡しています。 おそらく何通りも答えがありそうな予感がしております^^: ベストアンサーはまだですが、先にみなさまアドバイスありがとうございました。 結果: いくつかの方法を提示して頂けましたが、ファイルパス直打ちにしました。 アドバイス頂けたのに申し訳ないです。 中には私の理解不足で上手く試せてない方法もあります。 その他自分で試した方法として、一時テーブルを作成してサブクエリでfromを指定したりしてみましたが、ダメでした。 ベストアンサーを選んでからなので少し遅いですが、詳細な方法としては、下記の通りです。 ``` #!/bin/bash dbuser="hoge" dbconection=`cat ./db_conection` dbname=`cat ./db_name` dbpassword=`cat db_password` path=`pwd`"/import/" datpath=$path"data/" psql -h $dbconection -U $dbuser -d $dbname -f $path'sql/import.sql' -v datpath=$datpath ``` ``` \set filename hoge.csv \set inputfile '''':datpath:filename'''' \copy hoge from :inputfile with csv HEADER DELIMITER ','; -- 上記の:inputfileがどうしても展開されず・・・ ``` おそらくスクリプトの方を工夫することで問題の解決は図れそうですが、外部SQLの中が結構複雑で時間を考えて直打ちになりました。 せっかくアドバイス頂いたのに解決できずに申し訳ないです。 結果2 何度も申し訳ありません。 \copyコマンド自体をinputするという方法を上司に指南して頂きました。 スラッシュを2重にしないとダメなようでした。 ニッチすぎる情報ですが、誰かのお役に立てば。 ``` \set copycmd '\\copy hoge from ':inputfile' (format csv, header true);' :copycmd ```
回答: copyコマンドでもstdinで行えます ``` psql hogedb -c"copy tablename FROM stdin with csv HEADER DELIMITER ','" > ※なぜか「末尾に:がついているのも気になりますが・・・」 > > > copyはpostgresサーバへのコマンドSQL文と同じなので、;が必要です。 \copyはpsqlクライアントへのコマンドなのでsetと同様に不要です。 copyはリモートサーバで実行され入力ファイルは、そのサーバで参照可能な場所になります。 stdin,stdoutはサーバがクライアントのpsqlに対しての要求になりクライアントの入出力が可能となります。 ``` #!/bin/sh inputfile=hoge.csv psql hogedb -c"\copy hoge from '$inputfile' with csv HEADER DELIMITER ',';" ``` 要望されているのと違いますがstdinを使った場合 ``` #!/bin/sh psql hogedb<