Ich muss Daten aus einer alten Datenbank in eine neue mit leicht unterschiedlicher Struktur importieren. In der alten Datenbank gibt es beispielsweise eine Tabelle, in der Mitarbeiter und ihre Vorgesetzten aufgezeichnet werden:
CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)
Die neue Datenbank lautet nun wie folgt:
CREATE TABLE person (id BIGSERIAL PRIMARY KEY, name TEXT, old_ident TEXT);
CREATE TABLE team (id BIGSERIAL PRIMARY KEY);
CREATE TABLE teammember (person_id BIGINT, team_id BIGINT, role CHAR(1));
Das heißt, anstelle einer einfachen Tabelle mit Mitarbeitern mit den Namen ihrer Vorgesetzten können mit der neuen (allgemeineren) Datenbank Teams von Personen erstellt werden. Die Mitarbeiter sind Mitglieder mit Rolle 'e'
, Vorgesetzte mit Rolle 's'
.
Die Frage ist, wie die Daten einfach von employee
in die neue Struktur migriert werden können, ein Team pro Mitarbeiter-Vorgesetzter-Paar. Zum Beispiel Mitarbeiter
employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')
sind zu migrieren als
person: (1, 'John', 'abc01'), (2, 'Dave', NULL), (3, 'Kyle', 'abc02'), (4, 'Emily', NULL)
team: (1), (2)
teammember: (1, 1, 'e'), (2, 1, 's'), (3, 2, 'e'), (4, 2, 's')
Ich würde in Betracht ziehen, einen datenmodifizierenden CTE zu verwenden, bei dem zuerst die Mitarbeiter und Vorgesetzten und dann die Teams unter ihnen eingefügt werden. CTE kann jedoch nur Daten aus der eingefügten Tabellenzeile zurückgeben. Daher kann ich nicht mithalten, wer der Vorgesetzte von wem war.
Die einzige Lösung, die ich sehen kann, ist die Verwendung plpgsql
, bei der einfach die Daten durchlaufen, die eingefügten Team-IDs in einer temporären Variablen gespeichert und dann die entsprechenden teammember
Zeilen eingefügt werden . Aber ich bin gespannt, ob es einfachere oder elegantere Lösungen gibt.
Es werden ungefähr mehrere Hundert bis mehrere Tausend Mitarbeiter beschäftigt sein. Obwohl dies im Allgemeinen eine gute Vorgehensweise ist, möchte ich in meinem Fall die neuen IDs nicht basierend auf den alten generieren, da die alten IDs Zeichenfolgen ähneln *.GM2
. Ich speichere sie in der old_ident
Spalte als Referenz.
quelle
team
die die ID der Person enthält, für die das Team erstellt wurde, würde das Problem lösen. Ich bin immer noch gespannt, ob es eine elegantere Lösung gibt (dh ohne DDL).Antworten:
Sie haben alle Informationen, die Sie benötigen, um die neue Datenbank aus der alten mit 4 Einfügeanweisungen zu füllen:
Möglicherweise müssen Sie sich an den Geschmack anpassen. Ich gehe davon aus, dass employee.ident auf person.id abgebildet werden kann und dass Ihr DBMS das Zuweisen von Werten zu Spalten mit automatisch generierten Werten ermöglicht. Abgesehen davon ist es nur einfaches SQL, nichts Besonderes und natürlich keine Schleifen.
Zusätzlicher Kommentar:
SERIAL
(mit seinen 2 Milliarden Möglichkeiten) sollte reichlich sein, keine Notwendigkeit für aBIGSERIAL
.CHECK
oderFOREIGN KEY
Einschränkung für teammember.role? Vielleicht hat die Frage diese Details vereinfacht.quelle
person
Tabelle.PL / PgSQL erledigt den Job.
quelle