Necesito importar datos de una base de datos anterior a una nueva, con una estructura ligeramente diferente. Por ejemplo, en la base de datos anterior, hay una tabla que registra a los empleados y sus supervisores:
CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)
Ahora, la nueva base de datos es la siguiente:
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));
Es decir, en lugar de una simple tabla de empleados con los nombres de sus supervisores, la nueva base de datos (más genérica) permite crear equipos de personas. Los empleados son miembros con función 'e'
, supervisores con función 's'
.
La pregunta es cómo migrar fácilmente los datos employee
a la nueva estructura, un equipo por par empleado-supervisor. Por ejemplo, empleados
employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')
deben ser migrados como
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')
Consideraría usar un CTE modificador de datos, insertando primero a los empleados y supervisores, luego equipos entre ellos. Sin embargo, CTE solo puede devolver datos de la fila de tabla insertada. Por lo tanto, no puedo igualar quién era el supervisor de quién.
La única solución que puedo ver es usar plpgsql
, que simplemente iteraría sobre los datos, mantendría las ID de equipo insertadas en una variable temporal y luego insertaría las teammember
filas apropiadas . Pero tengo curiosidad por saber si hay soluciones más simples o más elegantes.
Habrá aproximadamente de varios cientos a varios miles de empleados. Aunque generalmente es una buena práctica, en mi caso, no me gustaría generar las nuevas ID basadas en las antiguas, ya que las ID antiguas son como cadenas *.GM2
. Los guardo en la old_ident
columna como referencia.
fuente
team
cual se guardaría la identificación de la persona para la cual se creó el equipo resolvería el problema. Sin embargo, todavía tengo curiosidad por saber si existe una solución más elegante (es decir, sin usar DDL).Respuestas:
Tiene toda la información que necesita para completar la nueva base de datos de la anterior con 4 instrucciones de inserción:
Puede que tenga que adaptarse al gusto. Supongo que employee.ident se puede asignar a person.id, y que su DBMS permite asignar valores a columnas con valores generados automáticamente. Excepto por eso, es solo SQL básico, nada sofisticado y, por supuesto , sin bucles.
Comentario adicional:
SERIAL
(con sus 2 mil millones de posibilidades) debería ser suficiente, sin necesidad de aBIGSERIAL
.CHECK
oFOREIGN KEY
limitación para teammember.role? Quizás la pregunta simplificó estos detalles.fuente
person
tabla.PL / PgSQL hará el trabajo.
fuente