Preciso importar dados de um banco de dados antigo para um novo, com estrutura ligeiramente diferente. Por exemplo, no banco de dados antigo, há uma tabela registrando os funcionários e seus supervisores:
CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)
Agora, o novo banco de dados é o seguinte:
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));
Ou seja, em vez de uma tabela simples de funcionários com os nomes de seus supervisores, o novo banco de dados (mais genérico) permite criar equipes de pessoas. Os funcionários são membros com função 'e'
, supervisores com função 's'
.
A questão é como migrar facilmente os dados employee
para a nova estrutura, uma equipe por par empregado-supervisor. Por exemplo, funcionários
employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')
devem 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')
Eu consideraria usar um CTE modificador de dados, inserindo os funcionários e supervisores primeiro, depois as equipes entre eles. No entanto, o CTE pode retornar apenas dados da linha da tabela inserida. Portanto, não sou capaz de igualar quem era o supervisor de quem.
A única solução que posso ver é usar plpgsql
, que simplesmente itera sobre os dados, mantém os IDs de equipe inseridos em uma variável temporária e insere as teammember
linhas apropriadas . Mas estou curioso para saber se existem soluções mais simples ou mais elegantes.
Haverá aproximadamente centenas a milhares de funcionários. Embora geralmente seja uma boa prática, no meu caso, eu não gostaria de gerar os novos IDs com base nos antigos, pois os IDs antigos são como strings *.GM2
. Eu os guardo na old_ident
coluna para referência.
fonte
team
qual conteria o ID da pessoa para a qual a equipe foi criada resolveria o problema. Ainda estou curioso para saber se existe uma solução mais elegante (ou seja, sem DDL).Respostas:
Você tem todas as informações necessárias para preencher o novo banco de dados do antigo com 4 instruções de inserção:
Você pode ter que ajustar a gosto. Suponho que employee.ident possa ser mapeado para person.id e que seu DBMS permita atribuir valores a colunas com valores gerados automaticamente. Exceto por isso, é apenas SQL básico, nada sofisticado e, é claro , sem loops.
Comentários adicionais:
SERIAL
(com seus 2 bilhões de possibilidades) deve ser suficiente, sem necessidade de aBIGSERIAL
.CHECK
ouFOREIGN KEY
para teammember.role? Talvez a questão tenha simplificado esses detalhes.fonte
person
tabela.O PL / PgSQL fará o trabalho.
fonte