Tenho feito desenvolvimento usando banco de dados SQLITE com produção em POSTGRESQL. Acabei de atualizar meu banco de dados local com uma grande quantidade de dados e preciso transferir uma tabela específica para o banco de dados de produção.
Com base na execução sqlite database .dump > /the/path/to/sqlite-dumpfile.sql
, o SQLITE gera um despejo de tabela no seguinte formato:
BEGIN TRANSACTION;
CREATE TABLE "courses_school" ("id" integer PRIMARY KEY, "department_count" integer NOT NULL DEFAULT 0, "the_id" integer UNIQUE, "school_name" varchar(150), "slug" varchar(50));
INSERT INTO "courses_school" VALUES(1,168,213,'TEST Name A',NULL);
INSERT INTO "courses_school" VALUES(2,0,656,'TEST Name B',NULL);
....
COMMIT;
Como faço para converter o acima em um arquivo de despejo compatível com POSTGRESQL que posso importar para o meu servidor de produção?
Respostas:
Você deve ser capaz de alimentar esse arquivo de despejo diretamente em
psql
:Se você quiser que a
id
coluna tenha um "incremento automático", altere seu tipo de "int" para "serial" na linha de criação da tabela. O PostgreSQL irá então anexar uma sequência àquela coluna para que INSERTs com ids NULL sejam automaticamente atribuídos ao próximo valor disponível. O PostgreSQL também não reconhecerá osAUTOINCREMENT
comandos, portanto, eles precisam ser removidos.Você também vai querer verificar as
datetime
colunas no esquema SQLite e alterá-lastimestamp
para PostgreSQL (obrigado a Clay por apontar isso).Se você tiver booleanos em seu SQLite, poderá converter
1
e0
e1::boolean
e0::boolean
(respectivamente) ou alterar a coluna booleana para um inteiro na seção de esquema do dump e corrigi-los manualmente dentro do PostgreSQL após a importação.Se você tiver BLOBs em seu SQLite, você desejará ajustar o esquema a ser usado
bytea
. Provavelmente, você também precisará misturar algumasdecode
chamadas . Escrever uma copiadora rápida e suja em sua linguagem favorita pode ser mais fácil do que mutilar o SQL se você tiver muitos BLOBs para lidar.Como de costume, se você tiver chaves estrangeiras, provavelmente desejará
set constraints all deferred
evitar problemas de ordem de inserção, colocando o comando dentro do par BEGIN / COMMIT.Agradecimentos a Nicolas Riley pelas notas booleanas, de bolhas e de restrições.
Se você tiver
`
em seu código, conforme gerado por alguns clientes SQLite3, será necessário removê-los.PostGRESQL também não reconhece
unsigned
colunas, você pode querer descartar isso ou adicionar uma restrição feita sob medida, como esta:Embora o padrão do SQLite para valores nulos
''
, o PostgreSQL requer que eles sejam configurados comoNULL
.A sintaxe no arquivo de despejo SQLite parece ser compatível com o PostgreSQL, portanto, você pode corrigir algumas coisas e alimentá-lo
psql
. A importação de uma grande pilha de dados por meio de SQL INSERTs pode demorar um pouco, mas funcionará.fonte
datetime
colunas sqlite , terá que alterá-lastimestamp
para o postgres.BLOB
paraBYTEA
( stackoverflow.com/questions/3103242 ), mudar 0/1 paraBOOLEAN
colunas para '0' / '1' e adiar restrições (DEFERRABLE
/SET CONSTRAINTS ALL DEFERRED
).pgloader
Me deparei com este post ao procurar uma maneira de converter um despejo SQLite para PostgreSQL. Mesmo que esta postagem tenha uma resposta aceita (e uma boa resposta com +1), acho que adicionar isso é importante.
Comecei a pesquisar as soluções aqui e percebi que estava procurando um método mais automatizado. Eu pesquisei os documentos wiki:
https://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL
e descoberto
pgloader
. Aplicativo muito legal e relativamente fácil de usar. Você pode converter o arquivo plano SQLite em um banco de dados PostgreSQL utilizável. Instalei do*.deb
e criei umcommand
arquivo como este em um diretório de teste:como o estado docs . Então criei um
testdb
comcreatedb
:createdb testdb
Eu executei o
pgloader
comando assim:pgloader command
e então conectado ao novo banco de dados:
psql testdb
Após algumas consultas para verificar os dados, parece que funcionou muito bem. Eu sei que se eu tivesse tentado executar um desses scripts ou fazer a conversão passo a passo mencionada aqui, teria gasto muito mais tempo.
Para provar o conceito, descartei isso
testdb
e importei para um ambiente de desenvolvimento em um servidor de produção e os dados foram transferidos de forma adequada.fonte
Eu escrevi um script para fazer o
sqlite3
parapostgres
a migração. Ele não lida com todas as traduções de esquema / dados mencionadas em https://stackoverflow.com/a/4581921/1303625 , mas faz o que eu precisava fazer. Esperançosamente, será um bom ponto de partida para outros.https://gist.github.com/2253099
fonte
A sequência gem (uma biblioteca Ruby) oferece cópia de dados em diferentes bancos de dados: http://sequel.jeremyevans.net/rdoc/files/doc/bin_sequel_rdoc.html#label-Copy+Databases
Primeiro instale o Ruby, depois instale o gem executando
gem install sequel
.No caso do sqlite, seria assim:
sequel -C sqlite://db/production.sqlite3 postgres://user@localhost/db
fonte
pgloader
.Você pode usar um liner, aqui está um exemplo com a ajuda do comando sed:
fonte
sed -e 's/DATETIME/TIMESTAMP/g'
sed -e 's/TINYINT(1)/SMALLINT/g'
- e para uma comparação de todos os tipos de dados, consulte stackoverflow.com/questions/1942586/…' | sed -e '
por;
:)Eu tentei editar / regexping o dump sqlite para que o PostgreSQL o aceite, é entediante e sujeito a erros.
O que eu tenho que trabalhar muito rápido:
Primeiro, recrie o esquema no PostgreSQL sem quaisquer dados, editando o dump ou se estiver usando um ORM, você pode ter sorte e ele se comunica com os dois back-ends (sqlalchemy, peewee, ...).
Em seguida, migre os dados usando o pandas. Suponha que você tenha uma tabela com um campo bool (que é 0/1 em sqlite, mas deve ser t / f em PostgreSQL)
Funciona muito bem, é fácil de escrever, ler e depurar cada função, ao contrário (para mim) das expressões regulares.
Agora você pode tentar carregar o csv resultante com PostgreSQL (mesmo graficamente com a ferramenta admin), com a única ressalva de que você deve carregar as tabelas com chaves estrangeiras depois de ter carregado as tabelas com as chaves de origem correspondentes. Eu não tive o caso de uma dependência circular, acho que você pode suspender temporariamente a verificação de chave se for o caso.
fonte
O pgloader faz maravilhas na conversão de banco de dados em sqlite para postgresql.
Aqui está um exemplo de conversão de um sqlitedb local em um banco de dados PostgreSQL remoto:
pgloader sqlite.db postgresql: // username : password @ hostname / dbname
fonte
KABOOM! Control stack exhausted (no more space for function call frames).