Daten importieren und exportieren

Bisher haben Sie gesehen, wie Daten mit Hilfe von INSERT in die Datenbank eingefügt werden können. Das ist denkbar ineffizient, da sehr viel Parsing Overhead entsteht. Um dieses Problem zu umgehen, kann COPY verwendet werden:

test=# \h COPY
Command:     COPY
Description: copy data between a file and a table
Syntax:
COPY tablename [ ( column [, ...] ) ]
    FROM { 'filename' | STDIN }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ QUOTE [ AS ] 'quote' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE NOT NULL column [, ...] ]

COPY tablename [ ( column [, ...] ) ]
    TO { 'filename' | STDOUT }
    [ [ WITH ]
          [ BINARY ]
          [ OIDS ]
          [ DELIMITER [ AS ] 'delimiter' ]
          [ NULL [ AS ] 'null string' ]
          [ CSV [ QUOTE [ AS ] 'quote' ]
                [ ESCAPE [ AS ] 'escape' ]
                [ FORCE QUOTE column [, ...] ]

COPY verfügt über effiziente Methoden, Daten direkt und ohne große Umwege in das Storage System zu schreiben. Das spart bei größeren Datenmengen sehr viel Zeit. Obwohl COPY zahlreiche Möglichkeiten bietet, ist die Performance trotzdem einzigartig.

Im folgenden Beispiel versuchen wir einen Teil von /etc/passwd in eine Tabelle zu kopieren. Zuallererst extrahieren wir die ersten 10 Zeilen aus der Datei:

[hs@athlon tmp]$ head /etc/passwd > import.txt
[hs@athlon tmp]$ cat import.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:

In weiterer Folge legen wir eine Tabelle an, die die einzelnen Spalten von /etc/passwd speichern kann:

test=# CREATE TABLE t_passwd (
	account 	text, 
	passwd 		text, 
	uid 		int4, 
	gid 		int4,
	gecos 		text, 
	directory 	text, 
	shell 		text);
CREATE TABLE

Um unsere Datei zu importieren, können wir nun COPY aufrufen:

test=# COPY t_passwd FROM '/tmp/import.txt' DELIMITER AS ':';
COPY

Als Trennzeichen (Delimiter) verwenden wir einen Doppelpunkt. Sofern das COPY funktioniert, werden wir die folgende Tabelle wiederfinden:

test=# SELECT * FROM t_passwd;
 account  | passwd | uid | gid |  gecos   |    directory    |     shell
----------+--------+-----+-----+----------+-----------------+----------------
 root     | x      |   0 |   0 | root     | /root           | /bin/bash
 bin      | x      |   1 |   1 | bin      | /bin            | /sbin/nologin
 daemon   | x      |   2 |   2 | daemon   | /sbin           | /sbin/nologin
 adm      | x      |   3 |   4 | adm      | /var/adm        | /sbin/nologin
 lp       | x      |   4 |   7 | lp       | /var/spool/lpd  | /sbin/nologin
 sync     | x      |   5 |   0 | sync     | /sbin           | /bin/sync
 shutdown | x      |   6 |   0 | shutdown | /sbin           | /sbin/shutdown
 halt     | x      |   7 |   0 | halt     | /sbin           | /sbin/halt
 mail     | x      |   8 |  12 | mail     | /var/spool/mail | /sbin/nologin
 news     | x      |   9 |  13 | news     | /etc/news       |
(10 rows)

Alle Werte werden fein säuberlich getrennt in Spalten ausgegeben. Wichtig zu wissen ist, dass der gesamte Datenbestand innerhalb einer Transaktion importiert wird - wenn COPY also abbricht, ist sichergestellt, dass kein Datenmüll in der Tabelle verbleibt. Man sagt, dass ein Import mit COPY um mindestens Faktor 6 schneller ist als mit INSERT. Klarerweise hängt das sehr stark von der Datenstruktur.

Wollen wir den Datenbestand anschließend wieder exportieren, können Sie wie folgt vorgehen:

test=# COPY t_passwd TO '/tmp/export' DELIMITER AS ':';
COPY

Wenn wir als Trennzeichen wieder einen Doppelpunkt verwenden, wird sich die Ergebnisdatei nicht vom Input unterscheiden:

[hs@athlon hs]$ diff /tmp/export /tmp/import.txt
[hs@athlon hs]$


Cybertec Schönig & Schönig GmbH
PostgreSQL support, training, consulting
www.postgresql-support.de