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.
使用 - copy_from
カーソル方式
f = open(r'C:\Users\n\Desktop\data.csv', 'r')
cur.copy_from(f, temp_unicommerce_status, sep=',')
f.close()
ファイルはオブジェクトとして渡す必要があります。
あなたはcsvファイルからコピーしているので、デフォルトはタブ文字であるため、セパレータを指定する必要があります
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"))
関連するPostgreSQLドキュメントからの抜粋は次のとおりです。ファイル名を指定したCOPYは、PostgreSQLサーバーにファイルの直接読み取りまたは書き込みを指示します。ファイルはサーバーからアクセス可能でなければならず、名前はサーバーの観点から指定する必要があります。 STDINまたはSTDOUTを指定すると、データはクライアントとサーバー間の接続を介して送信されます
これが、ファイルに対するcopy
コマンドがPostgreSQLスーパーユーザーに制限されている理由です。ファイルはサーバー上に存在する必要があり、サーバープロセスによって直接読み込まれます。
代わりに使用する必要があります:
cur.copy_from(r'C:\Users\n\Desktop\data.csv', temp_unicommerce_status)
この他の回答 で示唆されているように、内部的にはstdinのCOPY
を使用します。
この質問には答えられましたが、ここに私の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()
やった
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')
また、 データスキーマの変更 、テーブルの作成/追加/置換を処理し、パンダでデータを前処理できます。