Я занимаюсь разработкой с использованием базы данных 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, который я могу импортировать на свой производственный сервер?
Вы должны иметь возможность подавать этот файл дампа прямо в 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 может занять некоторое время, но он будет работать.
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
и импортировал в среду разработки на производственном сервере и переданные данные красиво.
Я написал script для переноса sqlite3
в postgres
. Он не обрабатывает все переводы схем/данных, упомянутые в https://stackoverflow.com/questions/4581727/convert-sqlite-sql-dump-file-to-postgresql, но он делает то, что мне нужно для этого. Надеюсь, это станет хорошей отправной точкой для других.
продолжение 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
Вы можете использовать один лайнер, вот пример с помощью команды 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
sed -e 's/DATETIME/TIMESTAMP/g'