diadia

興味があることをやってみる。自分のメモを残しておきます。

postgresqlにcopyでcsvデータを反映させる

copyを実行する方法

psqlコマンドでデータベースに接続した状態でcopyコマンドを実施する
psycopg2でpostgresqlに接続し、copy_fromメソッドを使ってcopyを実施する。
copy_expert(), execute()

できないこと、注意点1

csvファイルの指定カラムのみをテーブルにインポート
上記の記事を参考に色々試してみた。具体的には複数の列が存在するcsvファイルから特定の列のみコピーすることを試みた。上記の記事はテーブルにある複数のカラムから特定のカラムのみをcsvファイルのデータでコピーするということだと判断した。つまりcopyコマンドを実施する際にcsvファイルに含まれるデータはすべてコピー対象になってしまうのであって、csvファイルに含まれるデータから特定のデータのみを選んで反映させることではない、ということだ。

できないこと、注意点2

utf8には種類がありbomありとbomなしがある。bomありで保存することでintegerやdouble precisionなどのコピーが上手く出来ない事がわかった。一方charはコピーが上手く行った。windowsのメモ帳やエクセルでcsvを作成するときは注意すること。

psqlコマンドでデータベースに接続した状態でcopy

#データベースに接続する
psql -U ユーザー名 -d データベース名
#ex
psql -U postgres -d postgres

#copyコマンドの実行
\copy table名(userid, user_name) from 'csvのパス' with csv encoding 'utf8' ;
#ex
\copy my_test_table(userid, user_name) from 'C:\Users\USER\Desktop\sushi.csv' with csv encoding 'utf8' ; 

psycopg2でpostgresqlに接続し、copy_fromメソッドを使う

psycopg2で接続しcopy_fromメソッドでコピーする方法がある。
http://initd.org/psycopg/docs/cursor.html#cursor.copy_from
このメリットはプログラムの流れに沿ってcopyを実行することができることだ。しかしながらデメリットとしてcsvヘッダーを無視してコピーする事ができない事がある。コピーする前にヘッダーを削除してcopyを実行する事が必要だ。

#サンプル
import psycopg2

conn = psycopg2.connect(user="postgres", port=5432, dbname="postgres")
cur  = conn.cursor()

f = open('C:\\Users\\USER\\Desktop\\sushi.csv', mode='r', encoding='utf-8')
cur.copy_from(f, 'my_test_table', sep=',', columns=('serid', 'user_name'))
conn.commit()

f.close()

copy_expert

実際にpsqlに接続してcopyコマンドを実施するのと同じ機能を提供するらしい

http://initd.org/psycopg/docs/usage.html#using-copy-to-and-copy-fromhttp://initd.org/psycopg/docs/usage.html#using-copy-to-and-copy-from