J'ai besoin d'importer des données d'une ancienne base de données vers une nouvelle, avec une structure légèrement différente. Par exemple, dans l'ancienne base de données, il y a un tableau enregistrant les employés et leurs superviseurs:
CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)
Maintenant, la nouvelle base de données est la suivante:
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));
Autrement dit, au lieu d'un tableau simple des employés avec les noms de leurs superviseurs, la nouvelle base de données (plus générique) permet de créer des équipes de personnes. Les employés sont des membres avec rôle 'e'
, des superviseurs avec rôle 's'
.
La question est de savoir comment migrer facilement les données de employee
la nouvelle structure, une équipe par paire employé-superviseur. Par exemple, les employés
employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')
doivent être migrés
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')
J'envisagerais d'utiliser un CTE modificateur de données, en insérant d'abord les employés et les superviseurs, puis les équipes parmi eux. Cependant, CTE peut uniquement renvoyer des données de la ligne de table insérée. Ainsi, je ne suis pas en mesure de faire correspondre qui était le superviseur de qui.
La seule solution que je vois consiste à utiliser plpgsql
, ce qui permettrait simplement d'itérer sur les données, de conserver les ID d'équipe insérés dans une variable temporaire, puis d'insérer les teammember
lignes appropriées . Mais je suis curieux de savoir s'il existe des solutions plus simples ou plus élégantes.
Il y aura environ plusieurs centaines à plusieurs milliers d'employés. Bien que ce soit généralement une bonne pratique, dans mon cas, je ne voudrais pas générer les nouveaux ID sur la base des anciens, car les anciens ID sont des chaînes *.GM2
. Je les stocke dans la old_ident
colonne pour référence.
la source
team
auquel détiendrait l'ID de la personne pour laquelle l'équipe a été créée résoudrait le problème. Je suis toujours curieux de savoir s'il existe une solution plus élégante (c'est-à-dire n'utilisant pas de DDL).Réponses:
Vous disposez de toutes les informations nécessaires pour alimenter la nouvelle base de données à partir de l'ancienne avec 4 instructions d'insertion:
Vous devrez peut-être vous adapter au goût. Je suppose que employee.ident peut être mappé sur person.id et que votre SGBD permet d'attribuer des valeurs aux colonnes avec des valeurs générées automatiquement. À part ça, c'est juste du SQL basique, rien d'extraordinaire et, bien sûr , pas de boucles.
Commentaire supplémentaire:
SERIAL
(avec ses 2 milliards de possibilités) devrait être suffisant, pas besoin d'unBIGSERIAL
.CHECK
orFOREIGN KEY
pour teammember.role? Peut-être que la question a simplifié ces détails.la source
person
tableau.PL / PgSQL fera le travail.
la source