web-dev-qa-db-ja.com

pythonを使用してcsvからpostgresqlにデータをコピーします

Windows 7 64ビットを使用しています。 csvファイル「data.csv」があります。 pythonスクリプトを使用して、postgresqlテーブル 'temp_unicommerce_status'にデータをインポートしたい。

私のスクリプトは:

import psycopg2
conn = psycopg2.connect("Host='localhost' port='5432' dbname='Ekodev' user='bn_openerp' password='fa05844d'")
cur = conn.cursor()
cur.execute("""truncate table "meta".temp_unicommerce_status;""")
cur.execute("""Copy temp_unicommerce_status from 'C:\Users\n\Desktop\data.csv';""")
conn.commit()
conn.close()

このエラーが発生しています

Traceback (most recent call last):
  File "C:\Users\n\Documents\NetBeansProjects\Unicommerce_Status_Update\src\unicommerce_status_update.py", line 5, in <module>
cur.execute("""Copy temp_unicommerce_status from     'C:\\Users\\n\\Desktop\\data.csv';""")
psycopg2.ProgrammingError: must be superuser to COPY to or from a file
HINT:  Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.
13
Manish Gupta

使用 - copy_fromカーソル方式

f = open(r'C:\Users\n\Desktop\data.csv', 'r')
cur.copy_from(f, temp_unicommerce_status, sep=',')
f.close()

ファイルはオブジェクトとして渡す必要があります。

あなたはcsvファイルからコピーしているので、デフォルトはタブ文字であるため、セパレータを指定する必要があります

21
Clodoaldo Neto

Psychopg2カーソルクラス関数copy_expert(Docs: http://initd.org/psycopg/docs/cursor.html )を使用するためにこの問題を解決した方法。 copy_expertを使用すると、STDINを使用できるため、postgresユーザーのスーパーユーザー特権を発行する必要がありません。ファイルへのアクセスは、クライアント(linux/windows/mac)ユーザーのファイルへのアクセスに依存します。

Postgres COPY Docsから( https://www.postgresql.org/docs/current/static/sql-copy.html ):

COPYとpsqlの命令\ copyを混同しないでください。\copyは、COPY FROM STDINまたはCOPY TO STDOUTを呼び出してから、psqlクライアントがアクセスできるファイルにデータをフェッチ/格納します。したがって、\ copyを使用する場合、ファイルのアクセシビリティとアクセス権はサーバーではなくクライアントに依存します。

また、development_userホームフォルダーおよびAppフォルダーへのアクセスにのみアクセス許可を設定したままにすることもできます。

csv_file_name = '/home/user/some_file.csv'
sql = "COPY table_name FROM STDIN DELIMITER '|' CSV HEADER"
cursor.copy_expert(sql, open(csv_file_name, "r"))
5
jonnyjandles

関連するPostgreSQLドキュメントからの抜粋は次のとおりです。ファイル名を指定したCOPYは、PostgreSQLサーバーにファイルの直接読み取りまたは書き込みを指示します。ファイルはサーバーからアクセス可能でなければならず、名前はサーバーの観点から指定する必要があります。 STDINまたはSTDOUTを指定すると、データはクライアントとサーバー間の接続を介して送信されます

これが、ファイルに対するcopyコマンドがPostgreSQLスーパーユーザーに制限されている理由です。ファイルはサーバー上に存在する必要があり、サーバープロセスによって直接読み込まれます。

代わりに使用する必要があります:

cur.copy_from(r'C:\Users\n\Desktop\data.csv', temp_unicommerce_status)

この他の回答 で示唆されているように、内部的にはstdinのCOPYを使用します。

1
Serge Ballesta

この質問には答えられましたが、ここに私の2セントがあります。私はもう少し説明を追加しています:

cursor.copy_fromメソッドを使用できます:

最初に、csvファイルと同じ列数のテーブルを作成する必要があります。

例:

私のcsvは次のようになります:

Name,       age , college , id_no , country , state   , phone_no

demo_name   22  , bdsu    , 1456  , demo_co , demo_da , 9894321_

最初にテーブルを作成します。

import psycopg2
from psycopg2 import Error

connection = psycopg2.connect(user = "demo_user",
                                  password = "demo_pass",
                                  Host = "127.0.0.1",
                                  port = "5432",
                                  database = "postgres")
cursor = connection.cursor()


create_table_query = '''CREATE TABLE data_set
(Name  TEXT NOT NULL ,
age  TEXT NOT NULL ,
college  TEXT NOT NULL ,
id_no TEXT NOT NULL ,
country TEXT NOT NULL ,
state TEXT NOT NULL ,
phone_no TEXT NOT NULL);'''

cursor.execute(create_table_query)
connection.commit()

これで、3つのパラメーターが必要な場所で単純にcursor.copy_fromを使用できます。

first file object , second table_name , third sep type

今すぐコピーできます:

f = open(r'final_data.csv', 'r')
cursor.copy_from(f, 'data_set', sep=',')
f.close()

やった

0
Aaditya Ura

d6tstack を使用すると、これが簡単になります

import d6tstack
import glob

c = d6tstack.combine_csv.CombinerCSV([r'C:\Users\n\Desktop\data.csv']) # single-file
c = d6tstack.combine_csv.CombinerCSV(glob.glob('*.csv')) # multi-file
c.to_psql_combine('postgresql+psycopg2://psqlusr:psqlpwdpsqlpwd@localhost/psqltest', 'tablename')

また、 データスキーマの変更 、テーブルの作成/追加/置換を処理し、パンダでデータを前処理できます。

0
citynorman