Ich bin unter Windows 7 64 Bit . Ich habe eine CSV-Datei 'data.csv' . Ich möchte Daten über ein Python-Skript in eine Postgresql-Tabelle 'temp_unicommerce_status' importieren.
Mein Skript lautet:
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()
Ich bekomme diesen Fehler
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.
Verwenden Sie die Cursormethode copy_from
f = open(r'C:\Users\n\Desktop\data.csv', 'r')
cur.copy_from(f, temp_unicommerce_status, sep=',')
f.close()
Die Datei muss als Objekt übergeben werden.
Da Sie aus einer CSV-Datei kopieren, müssen Sie das Trennzeichen angeben, da standardmäßig ein Tabulatorzeichen verwendet wird
Die Art und Weise, wie ich dieses Problem gelöst habe, war insbesondere die Verwendung der psychopg2-Cursor-Klassenfunktion copy_expert (Docs: http://initd.org/psycopg/docs/cursor.html ). Mit copy_expert können Sie STDIN verwenden, wodurch die Notwendigkeit der Ausgabe eines Superuser-Privilegs für den postgres-Benutzer umgangen wird. Ihr Zugriff auf die Datei hängt dann vom Zugriff des Clientbenutzers (Linux/Windows/Mac) auf die Datei ab
Aus COPY-Dokumenten von Postgres ( https://www.postgresql.org/docs/current/static/sql-copy.html ):
Verwechseln Sie COPY nicht mit der Anweisung psql\copy.\copy ruft .__ auf. COPY FROM STDIN oder COPY TO STDOUT und holt/speichert dann die Daten in eine Datei, auf die der psql-Client zugreifen kann. Also, Dateizugriff und Zugriffsrechte hängen vom Client und nicht vom Server ab, wenn\copy wird eingesetzt.
Sie können die Berechtigungen auch strikt für den Zugriff auf den Home-Ordner development_user und den App-Ordner festlegen.
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"))
Hier ein Auszug aus der relevanten PostgreSQL-Dokumentation: COPY mit einem Dateinamen weist den PostgreSQL-Server an, direkt aus einer Datei zu lesen oder in diese zu schreiben. Die Datei muss für den Server zugänglich sein, und der Name muss aus Sicht des Servers angegeben werden. Wenn STDIN oder STDOUT angegeben ist, werden Daten über die Verbindung zwischen Client und Server übertragen.
Aus diesem Grund ist der Befehl copy
in eine oder aus einer Datei auf einen PostgreSQL-Superuser beschränkt: Die Datei muss auf dem Server vorhanden sein und wird direkt vom Serverprozess geladen.
Sie sollten stattdessen verwenden:
cur.copy_from(r'C:\Users\n\Desktop\data.csv', temp_unicommerce_status)
wie von dieser anderen Antwort vorgeschlagen , weil intern COPY
von stdin verwendet wird.
Ich weiß, dass diese Frage beantwortet wurde, aber hier sind meine zwei Cent. Ich füge etwas mehr Beschreibung hinzu:
Sie können die cursor.copy_from
-Methode verwenden:
Zuerst müssen Sie eine Tabelle mit derselben Spaltenanzahl wie Ihre CSV-Datei erstellen.
Beispiel:
Meine CSV sieht so aus:
Name, age , college , id_no , country , state , phone_no
demo_name 22 , bdsu , 1456 , demo_co , demo_da , 9894321_
Erstellen Sie zuerst eine Tabelle:
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()
Jetzt können Sie einfach cursor.copy_from verwenden, wo Sie drei Parameter benötigen:
first file object , second table_name , third sep type
sie können jetzt kopieren:
f = open(r'final_data.csv', 'r')
cursor.copy_from(f, 'data_set', sep=',')
f.close()
erledigt
Sie können d6tstack verwenden, was dies einfach macht
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:[email protected]/psqltest', 'tablename')
Es befasst sich auch mit Datenschemaänderungen , Erstellen/Anfügen/Ersetzen von Tabelle und ermöglicht es Ihnen, Daten mit Pandas vorzuverarbeiten.