Конвертировать SQL-файл дампа SQLITE в POSTGRESQL - PullRequest
82 голосов
/ 03 января 2011

Я занимался разработкой с использованием базы данных 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 файл дампа, который я могу импортировать на свой рабочий сервер?

Ответы [ 7 ]

88 голосов
/ 03 января 2011

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

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

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

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

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

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

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

Спасибо Николасу Райли за логические примечания, BLOB-объекты и ограничения.

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

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

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

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

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

55 голосов
/ 30 мая 2015

pgloader

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

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

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 .Затем я создал testdb с createdb:

createdb testdb

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

pgloader command

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

psql testdb

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

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

15 голосов
/ 30 марта 2012

Я написал скрипт для миграции с sqlite3 на postgres.Он не обрабатывает все переводы схемы / данных, упомянутые в https://stackoverflow.com/a/4581921/1303625,, но делает то, что мне было нужно.Надеюсь, это станет хорошей отправной точкой для других.

https://gist.github.com/2253099

11 голосов
/ 20 июля 2015

Gem sequel *1002* (библиотека 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

7 голосов
/ 19 сентября 2014

Вы можете использовать один вкладыш, вот пример с помощью команды 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 голосов
/ 08 мая 2019

Я попытался отредактировать / пересмотреть дамп sqlite, чтобы PostgreSQL его принял, он утомителен и подвержен ошибкам.

То, что я получил на работу очень быстро:

Сначала заново создайте схему на PostgreSQL без каких-либо данных, либо отредактировав дамп, либо, если вы использовали ORM, вам может повезти, и он общается с обоими бэкэндами (sqlalchemy, peewee, ...).

Затем перенесите данные с помощью панд. Предположим, у вас есть таблица с полем bool (в sqlite это 0/1, но в PostgreSQL должно быть t / f)

def int_to_strbool(df, column):
    df = df.replace({column: 0}, 'f')
    df = df.replace({column: 1}, 't')
    return df

#def other_transform(df, column):
#...

conn = sqlite3.connect(db)
df = pd.read_sql(f'select * from {table_name}', conn)

df = int_to_strbool(df, bool_column_name)
#df = other_transform(df, other_column_name)

df.to_csv(table_name + '.csv'), sep=',', header=False, index=False)

Это работает как шарм, легко писать, читать и отлаживать каждую функцию, в отличие от (для меня) регулярных выражений.

Теперь вы можете попытаться загрузить получившийся csv с PostgreSQL (даже графически с помощью инструмента администратора), с единственной оговоркой, что вы должны загружать таблицы с внешними ключами после того, как вы загрузили таблицы с соответствующими исходными ключами. У меня не было случая циклической зависимости, я думаю, вы можете временно приостановить проверку ключа, если это так.

0 голосов
/ 05 сентября 2018

pgloader творит чудеса при преобразовании базы данных в sqlite в postgresql.

Вот пример преобразования локального sqlitedb в удаленный db PostgreSQL:

pgloader sqlite.db postgresql: // имя пользователя : пароль @ имя хоста / имя_базы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...