2016-03-22 8 views
0

ich viel Zeit verbracht haben, diese Erforschung und haben nicht wirklich etwas gefunden das alles zu erklären, um so hier kann ich bin der Hoffnung, jemand helfen. Ich schreibe gerade ein Programm, um große Datenmengen (möglicherweise Dutzende von GBs) zu säubern und in eine Postgres-Tabelle einzugeben.PostgreSQL Kopie von Datei vs STDIN

Meine aktuelle Setup hat mir das Einlesen und die ursprünglichen CSV-Daten in eine frische CSV-Datei reinigen, bevor dann COPY FROM-Befehl ausgeführt wird in dieser frischen CSV-Datei in die Tabelle zu lesen.

Es gibt einige offensichtliche Probleme mit diesem, einschließlich im Grunde die Datei 2-3 mal lesen, sowie doppelte Speicherplatz erforderlich. Es scheint ineffizient zu sein, in eine neue Datei zu lesen und diese Datei dann in Postgres zu lesen, anstatt sie einfach direkt in STDIN der Postgres-Shell zu streamen und sie direkt in die Tabelle einzufügen.

Wenn jemand eine Erfahrung im Umgang mit zu ähnlichen Problem hat, haben Sie finden es schneller/möglich, einfach eine Datei zu STDIN von Postgres zu streamen? Ich implementiere dies in Java, also wird jede und jede Hilfe, die ich mit diesem Problem bekommen kann, sehr geschätzt!

Danke!

+1

Sie können die 'CopyManager'-Unterstützung aus dem JDBC-Treiber verwenden: https://jdbc.postgresql.org/documentation/publicapi/org/postgresql/copy/CopyManager.html –

+0

Ich habe versucht, das zu verwenden, aber nicht in der Lage gewesen, um herauszufinden, wie man „Strom“ die Daten an den STDIN von Postgres, was ich am Ende tun wird nur die copyin Funktion am Ende meiner Reinigung aufrufen und die SQL-Anweisung sowie die Filereader vorbei was hat meine gereinigte Datei geöffnet. Haben Sie einen Beispielcode oder eine Erklärung, wie ich jede CSV-Zeile in die STDIN einfügen soll, wenn sie von der Reinigung kommt? – schriste92

+0

'copyIn()' nimmt nur einen 'Reader' als Parameter. Machen Sie Ihre „Reinigungscode“, der Schnittstelle implementieren und dann das passieren zum CopyManager –

Antwort

0

Verwenden Sie PipedInputStream und PipedOutputStream zusammen, sodass Sie direkt aus der CSV-Quelldatei lesen und dann in den in der Funktion copyIn() verwendeten inputStream schreiben können. Hier ist ein Beispiel:

PipedInputStream is = new PipedInputStream(); 
PipedOutputStream os = new PipedOutputStream(is); 
BufferedReader br = new BufferedReader(new InputStreamReader(is)); 
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os)); 
BufferedReader fr = new BufferedReader(new FileReader("path/to/file")); 

als von fr lesen und schreiben zu bw. Ich denke du könntest einen Teil der Codes schreiben. :)