Конвертировать SQL-файл дампа SQLITE в POSTGRESQL

65

Я занимаюсь разработкой с использованием базы данных SQLITE с производством в POSTGRESQL. Я просто обновил свою локальную базу данных с огромным объемом данных и вам нужно перенести определенную таблицу в производственную базу данных.

Основываясь на запуске sqlite database .dump > /the/path/to/sqlite-dumpfile.sql, SQLITE выводит дамп таблицы в следующем формате:

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;

Как мне преобразовать вышеуказанное в файл дампа, совместимый с POSTGRESQL, который я могу импортировать на свой производственный сервер?

  • 1
    Ну, эта команда не работает для меня, пока я не изменил sqlite на sqlite3
Теги:
database
migration

5 ответов

72
Лучший ответ

Вы должны иметь возможность подавать этот файл дампа прямо в psql:

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

Если вы хотите, чтобы столбец id имел значение "auto increment", измените его тип с "int" на "serial" в строке создания таблицы. PostgreSQL затем присоединяет последовательность к этому столбцу, так что INSERT с идентификаторами NULL будет автоматически назначено следующее доступное значение. PostgreSQL также не распознает команды AUTOINCREMENT, поэтому их необходимо удалить.

Вы также захотите проверить столбцы datetime в схеме SQLite и изменить их на timestamp для PostgreSQL (благодаря Clay для указания это).

Если у вас есть booleans в вашем SQLite, вы можете конвертировать 1 и 0 и 1::boolean и 0::boolean (соответственно), или вы можете изменить булевский столбец на целое число в разделе схемы дампа и затем закрепите их вручную в PostgreSQL после импорта.

Если у вас есть BLOB в вашем SQLite, вам нужно настроить схему для использования bytea. Вероятно, вам нужно будет перемешать несколько вызовов decode. Написание quick'n'dirty copier на вашем любимом языке может быть проще, чем манипулировать SQL, если вам нужно много BLOB файлов.

Как обычно, если у вас есть внешние ключи, вы, вероятно, захотите заглянуть в set constraints all deferred, чтобы избежать проблем с упорядочением порядка размещения, команды внутри пары BEGIN/COMMIT.

Благодаря Nicolas Riley для заметок boolean, blob и constraints.

Если у вас есть ` в вашем коде, созданный некоторыми клиентами SQLite3, вам необходимо удалить их.

PostGRESQL также не распознает столбцы unsigned, вы можете отказаться от этого или добавить настраиваемое ограничение, такое как:

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

В то время как значения SQLite по умолчанию равны нулю для '', PostgreSQL требует, чтобы они были установлены как NULL.

Синтаксис в файле дампа SQLite, по-видимому, в основном совместим с PostgreSQL, поэтому вы можете исправлять несколько вещей и передавать их на psql. Импорт большой кучи данных через SQL INSERT может занять некоторое время, но он будет работать.

  • 0
    Спасибо! Спасибо! Это отлично сработало для меня. Сначала у меня была программа, выполняющая эту миграцию, но она была слишком медленной и вызывала другие проблемы. Исправление к вашей команде. Это должно быть -D, а не -D.
  • 0
    Одно замечание: если у кого-то еще есть эта проблема, то в SQLITE мои нулевые значения были равны ''. POSTGRESQL требует NULL. Запустите vim и выполните команду:% s / '' / NULL / g, чтобы исправить файл дампа.
Показать ещё 16 комментариев
28

pgloader

Я столкнулся с этим сообщением при поиске способа преобразования дампа SQLite в PostgreSQL. Несмотря на то, что у этого сообщения есть принятый ответ (и хороший на +1), я думаю, что это важно.

Я начал изучать решения здесь и понял, что я искал более автоматический метод. Я просмотрел документы wiki:

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

и обнаружил pgloader. Довольно крутое приложение, и оно относительно прост в использовании. Вы можете преобразовать плоский файл SQLite в полезную базу данных PostgreSQL. Я установил из *.deb и создал файл command, как это, в тестовом каталоге:

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';

как состояние docs. Затем я создал a testdb с createdb:

createdb testdb

Я запустил команду pgloader следующим образом:

pgloader command

а затем подключиться к новой базе данных:

psql testdb

После некоторых запросов, чтобы проверить данные, кажется, что это сработало достаточно хорошо. Я знаю, что если бы я попытался запустить один из этих сценариев или сделать ступенчатое преобразование, упомянутое здесь, я потратил бы гораздо больше времени.

Чтобы доказать концепцию, я сбросил этот testdb и импортировал в среду разработки на производственном сервере и переданные данные красиво.

  • 0
    Супер инструмент, работает как шарм, прост в использовании!
  • 1
    Помните, что (все еще поддерживаемые) дистрибутивы Ubuntu могут иметь устаревшую версию - v2.xy уже устарела и фактически не работает. v3.2.x может работать, но рекомендуется v3.2.3. Я извлек v3.2.3 из передовой и установил с sudo dpkg -i <имя файла .deb> , у него не было проблем с зависимостями.
Показать ещё 4 комментария
14

Я написал script для переноса sqlite3 в postgres. Он не обрабатывает все переводы схем/данных, упомянутые в https://stackoverflow.com/questions/4581727/convert-sqlite-sql-dump-file-to-postgresql, но он делает то, что мне нужно для этого. Надеюсь, это станет хорошей отправной точкой для других.

https://gist.github.com/2253099

  • 2
    Это хорошо работает! Я разобрал Gist и добавил некоторые идеи в качестве комментария: gist.github.com/bittner/7368128
8

продолжение gem (библиотека Ruby) предлагает копирование данных в разных базах данных: http://sequel.jeremyevans.net/rdoc/files/doc/bin_sequel_rdoc.html#label-Copy+Databases

В случае sqlite это будет выглядеть так: sequel -C sqlite://db/production.sqlite3 postgres://user@localhost/db

8

Вы можете использовать один лайнер, вот пример с помощью команды sed:

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
    нет замены для типа LONG, например
  • 1
    можно добавить еще один элемент sed -e 's/DATETIME/TIMESTAMP/g'
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню