Migration auf Abfrage basierend

Hallo zusammen,

leider konnte ich in der Postgres-Doku keinen geeignete Informationen zu folgendem Problem finden.

Es liegt eine Datenbank mit z.T. inkonsistenten Kundendaten vor. Anhand gültiger Verträge würde ich gern die Kunden selektieren, die “richtig” sind und in einen neue Datenbank importieren.

Nun habe ich gehofft, dass Postgres eine Funktion hat, die es ermöglicht alle abhängigen Datensätze eines Datensatzes zu ermitteln und genau diese Ergebnismenge zu dumpen.

Hat eventuell jemand von Euch eine Idee wie ich vorgehen könnte?

Viele Grüße.

Deine Problembeschreibung ist vage, vielleicht habe ich es auch komplett falsch geparst. Mal sehen.

Du hast z.B. 2 Tabellen, hier master und slave genannt:

test=# select * from master;
id | name
----±--------
1 | master1
2 | master2
(2 rows)

test=*# select * from client;
id | name
----±----------
1 | client1_1
1 | client1_2
2 | client2_1
3 | client3_1
(4 rows)

Der Datensatz mit id=3 in slave ist offensichtlich falsch, er hat keinen Bezug (mehr) in Master.
Du willst nun alle gültigen/ungültigen Datensätze aus slave:

test=*# select * from client where id in (select id from master);
id | name
----±----------
1 | client1_1
1 | client1_2
2 | client2_1
(3 rows)

test=*# select * from client where id not in (select id from master);
id | name
----±----------
3 | client3_1
(1 row)


Nach diesem Verfahren könntest Du nun z.B. eine neue Tabelle für slave erzeugen, die gültige Daten enthält:

test=*# create table new_slave as select * from client where id in (select id from master);
SELECT


Und dann dafür sorgen, daß Deine RI in Zukunft erhalten bleibt:

test=# alter table master add primary key (id);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index “master_pkey” for table “master”
ALTER TABLE
test=*# alter table new_slave add constraint fk foreign key (id) references master(id);
ALTER TABLE


Falls Dir das nichtweiterhilft, würde uns es helfen, wenn Du mehr Details (Aufbau der Tabellen etc.) liefern könntest.

Ok ich versuche es etwas genauer zu erklären:

Tabelle client

id | client_nr | name

1 | N5 | client_1
2 | N5 | client_1
4 | N6 | client_2
5 | N7 | client_3

Tabelle contract

id | client_id | contract_number

1 | 1 | AN1001
2 | 2 | AN1002

Hier ist das Problem : Die Einträge in client sind nicht eindeutig nach client_nr, so dass Contracts einmal an die client_id=1 und an die client_id=2 gehängt wurden, obwohl sämtliche Contracts zur client_nr=N5 an client_id=1 hängen müßten. Das hängt mit dem Frontend zusammen, der Anwender sieht nur die client_nr.

Meine Idee war nun alle Contracts zu selektieren und nur die Clients zu übernehmen, die mit einem Contract verbunden sind. Um die Datenmenge “sinnloser” Sätze in Client schonmal etwas zu reduzieren.

Ich dachte es gäbe dann eine Funktion, die sämtliche Datensätze aus allen zu clients abhängigen Tabellen (Verknüpft mit Foreign Keys) mit selektiert.

Es handelt sich auch nicht nur um zwei Tabellen, sondern um wesentlich mehr.

Nun, du könntest einen ganz normalen Join darüber laufen lassen, der die Datensätze verknüpft. Die nicht vorhandenen auf einer Seite werden dabei ausgelassen.

Wenn ich dein Problem jetzt richtig verstanden habe …

Genau. Und wie bekomme ich die Daten in die neue Datenbank?

Das Resultat Deiner Bereinigung z.B. in einer neuen Tabelle speichern und dann die Tabellen halt umbenennen.

Also

create table new_table as select …
dann die alte tabelle zu old_table umbenennen und dann new_table in table umbenennen.

Sorry, wenn ich jetzt etwas umständlich bin:

Also das Ergebnis des Joins enthält doch Datensätze aus mehreren Tabellen, die auch wieder in diesselben Tabellen aufgesplittet werden sollen.

Ich könnte das Join-Ergebnis mit “create table new_table as select” in eine Tabelle speichern. Und aus dieser Tabelle die Daten dann wieder splitten.

Das könnte funktionieren.