python で リモートサーバーにある postgresql の copy コマンドを実行する
python で リモートサーバー(python 実行とは異なるサーバー)にある postgresql の copy コマンドを実行したときの挙動についてメモ
ライブラリ
psycopg2 というやつを使いました。
調べるとpython copy postgresql なんかで検索するといろいろ情報出てきた。
やり方
いろいろやり方はある
copy_to / copy_from
conn = psycopg2.connect("dbname=test user=postgres") cur = conn.cursor() f = open("./output.csv") cur.copy_to(f, table_name)
copy_expert
conn = psycopg2.connect("dbname=test user=postgres") cur = conn.cursor() cur.copy_expert("COPY db_name.table_name FROM file_name) i
execute
conn = psycopg2.connect("dbname=test user=postgres") cur = conn.cursor() cur.execute("COPY db_name.table_name FROM file_name")
あまりちゃんと調べていないので、copy_expert と execute の違いが理解していませんが。。
リモート/ローカルの違い
あえてタイトルに「リモートサーバーにある」 postgresql と書いているのには理由があって、プログラム実行コマンドとDBのサーバーが異なると、動きが違った。
command | ローカル | リモート |
---|---|---|
copy_to | ○ | ○ |
copy_expert | ○ | × |
execute | ○ | × |
上記の○はリモートDBのデータをローカルにファイルで保存できるかどうか。 copy_from (ローカルのファイルを読み込んでリモートDBに登録)も同じ結果だった。 copy_expert や execute では、おそらくリモートDBのサーバー内のファイルを指定されたと認識するような挙動になった。
copy_to はテーブル指定のみ
copy_to / from が用意されているので普通に使えばいいのだが、少し困ったのがcopy_toでクエリ指定したいとき。 copy_to はテーブル名の指定しかできないため、任意のクエリによる結果を抽出できない。
なのでtemporary table を作成して、そこから copy_to することにした。 またpostgresql 10 からは、view からも copy できるようです。