2011-01-03 15 views
70

Ich habe Entwicklung mit SQLITE-Datenbank mit der Produktion in POSTGRESQL. Ich habe gerade meine lokale Datenbank mit einer großen Menge an Daten aktualisiert und muss eine bestimmte Tabelle in die Produktionsdatenbank übertragen.SQLITE SQL-Dump-Datei in POSTGRESQL konvertieren

Basierend auf sqlite database .dump > /the/path/to/sqlite-dumpfile.sql läuft, SQLITE gibt eine Tabelle Dump in folgendem Format:

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; 

Wie konvertiere ich die oben in eine POSTGRESQL kompatible Dump-Datei, die ich in meinem Produktions-Server importieren?

Antwort

74

Sie sollten in der Lage sein, diese Abbild-Datei direkt in psql zu füttern:

/path/to/psql -d database -U username -W < /the/path/to/sqlite-dumpfile.sql 

Wenn Sie die id Spalt „Zuwachs auto“ zu wollen, dann seinen Typen von „int“ auf „serielle“ in der Tabelle Erstellungslinie. PostgreSQL wird dann eine Sequenz an diese Spalte anhängen, so dass INSERTs mit NULL-IDs automatisch den nächsten verfügbaren Wert zugewiesen bekommt. PostgreSQL erkennt auch keine AUTOINCREMENT Befehle, daher müssen diese entfernt werden.

Sie werden auch für datetime Spalten in der SQLite-Schema überprüfen möchten und sie für PostgreSQL (dank Clay für diesen Hinweis) zu timestamp ändern.

Wenn Sie booleans in Ihrem SQLite haben dann Sie 1 und 0 und 1::boolean und 0::boolean (jeweils) umwandeln könnten oder könnten Sie die Boolesche Spalte auf eine ganze Zahl im Schema Abschnitt der Deponie ändern und sie dann von Hand reparieren innen PostgreSQL nach dem Import.

Wenn Sie BLOBs in Ihrer SQLite haben, sollten Sie das Schema so anpassen, dass es bytea verwendet. Sie müssen wahrscheinlich einige decode calls as well mischen. Das Schreiben eines Schnellkopierers in Ihrer Lieblingssprache ist möglicherweise einfacher als die SQL-Bearbeitung, wenn Sie viele BLOBs verwenden.

Wie üblich, wenn Sie Fremdschlüssel haben, dann werden Sie wahrscheinlich in suchen, um Probleme mit der Reihenfolge der Einfügung zu vermeiden, indem Sie den Befehl innerhalb des BEGIN/COMMIT-Paares platzieren.

Dank Nicolas Riley für die Boolean, Blob und Constraints Hinweise.

Wenn Sie in Ihrem Code ` haben, wie von einigen SQLite3-Clients generiert, müssen Sie sie entfernen.

PostGRESQL erkennt auch nicht unsigned Spalten, könnten Sie, dass die gelöscht werden soll, oder eine maßgeschneiderte Einschränkung wie hinzufügen:

CREATE TABLE tablename (
    ... 
    unsigned_column_name integer CHECK (unsigned_column_name > 0) 
); 

Während SQLite Standardwerte Nullwerte '', erfordert PostgreSQL sie als NULL eingestellt werden.

Die Syntax in der SQLite-Dump-Datei scheint größtenteils mit PostgreSQL kompatibel zu sein, so dass Sie einige Dinge patchen und an psql füttern können. Das Importieren eines großen Datenstapels durch SQL-INSERTs kann eine Weile dauern, aber es wird funktionieren.

+0

Thank you! Vielen Dank! Das hat super für mich funktioniert. Ich hatte ein Programm, das diese Migration zuerst machte, aber es war viel zu langsam und verursachte andere Probleme. Korrektur zu Ihrem Befehl. Es sollte -d, nicht -D sein. – DevX

+0

Ein Hinweis, wenn jemand anderes dieses Problem hat, hatte SQLITE meine Null-Werte als "". POSTGRESQL benötigt NULL. Also starte vim und führe den Befehl:% s/''/NULL/g, um die Dump-Datei zu reparieren. – DevX

+4

Nein, Sie möchten die Transaktion beibehalten, um einen gewissen Mehraufwand zu vermeiden. –

14

Ich schrieb ein Skript für die Migration sqlite3 zu postgres.Es behandelt nicht alle Schema/Daten-Übersetzungen, die in https://stackoverflow.com/a/4581921/1303625 erwähnt werden, aber es tut, was ich dazu brauchte. Hoffentlich wird es ein guter Ausgangspunkt für andere sein.

https://gist.github.com/2253099

+2

Das funktioniert gut! Ich habe den Gist gegabelt und einige Einsichten als Kommentar hinzugefügt: https://gist.github.com/bittner/7368128 – Peterino

8

Sie können einen Einzeiler verwenden, hier ist ein Beispiel mit Hilfe von sed Befehl:

sqlite3 mjsqlite.db .dump | sed -e 's/INTEGER PRIMARY KEY AUTOINCREMENT/SERIAL PRIMARY KEY/' | sed -e 's/PRAGMA foreign_keys=OFF;//' | sed -e 's/unsigned big int/BIGINT/g' | sed -e 's/UNSIGNED BIG INT/BIGINT/g' | sed -e 's/BIG INT/BIGINT/g' | sed -e 's/UNSIGNED INT(10)/BIGINT/' | sed -e 's/BOOLEAN/SMALLINT/g' | sed -e 's/boolean/SMALLINT/g' | sed -e 's/UNSIGNED BIG INT/INTEGER/g' | sed -e 's/INT(3)/INT2/g' | sed -e 's/DATETIME/TIMESTAMP/g' | psql mypqdb mypguser 
+0

Es gibt keinen Ersatz für den LONG-Typ, z. – yetanothercoder

+1

ein weiterer Punkt könnte hinzugefügt werden 'sed -e '/ DATETIME/TIMESTAMP/g'' – silpol

+0

' sed -e'/TINYINT (1)/SMALLINT/g'' - und für einen Vergleich aller Daten Typen siehe https://stackoverflow.com/questions/1942586/comparison-of-database-column-types-in-mysql-postgresql-and-sqlite-cross-map – Purplejacket

29

pgloader

ich auf diesen Beitrag kam, als Suche nach einem Weg zu Konvertieren eines SQLite-Dumps in PostgreSQL. Obwohl dieser Post eine akzeptierte Antwort hat (und eine gute bei +1), denke ich, dass das Hinzufügen wichtig ist.

Ich fing an, die Lösungen hier zu untersuchen und erkannte, dass ich nach einer mehr automatisierten Methode suchte. Ich sah die Wiki-docs up:

https://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL

und entdeckt pgloader. Ziemlich coole Anwendung und es ist relativ einfach zu bedienen. Sie können die flache SQLite-Datei in eine verwendbare PostgreSQL-Datenbank konvertieren. Ich installierte vom *.deb und erstellt eine command Datei wie folgt in einem Testverzeichnis:

load database 
    from 'db.sqlite3' 
    into postgresql:///testdb 

with include drop, create tables, create indexes, reset sequences 

set work_mem to '16MB', maintenance_work_mem to '512 MB'; 

wie der docs Zustand. Ich habe dann ein testdb mit createdb:

pgloader command

und dann mit der neuen Datenbank:

psql testdb

createdb testdb

ich den pgloader Befehl so lief

Nach einigen Abfragen, um die Daten zu überprüfen, scheint es recht gut zu funktionieren. Ich weiß, wenn ich versucht hätte, eines dieser Skripte auszuführen oder die hier erwähnte schrittweise Umwandlung durchzuführen, hätte ich viel mehr Zeit dafür aufgewendet.

Um das Konzept zu beweisen, habe ich diese testdb und in eine Entwicklungsumgebung auf einem Produktionsserver importiert und die Daten über schön übertragen.

+0

Super-Tool, funktioniert wie ein Charme, einfach zu bedienen! – Hannes

+1

Vorsicht, (noch unterstützt) Ubuntu-Distributionen haben möglicherweise eine veraltete Version - v2.x.y ist bereits veraltet und funktioniert nicht mehr. v3.2.x funktioniert möglicherweise, aber v3.2.3 wird empfohlen. Ich habe v3.2.3 von blutenden Rand geholt und mit _sudo dpkg -i <.deb Dateiname> _ installiert, es hatte kein Problem mit Abhängigkeiten. – silpol

+0

Ich stimme mit @silpol überein - stellen Sie sicher, dass Sie die neueste stabile Version herunterladen und mit Ihrem fav Paketmanager installieren. Für die "Befehls" -Datei ist dies nur eine Textdatei namens "Befehl" ohne Erweiterungsname (d. h. keine Notwendigkeit für .txt am Ende des Dateinamens). Sie müssen den Dateinamen nicht in spitze Klammern setzen; Ich musste den search_parth der psql-Datenbank ändern, um meine Daten zu sehen; pgloader funktioniert gut und erspart mir eine Menge Ärger – BKSpurgeon

Verwandte Themen