Я занимаюсь разработкой с использованием базы данных 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
:Если вы хотите, чтобы
id
столбец «увеличивался автоматически», измените его тип с «int» на «serial» в строке создания таблицы. PostgreSQL затем присоединит последовательность к этому столбцу, чтобы вставкам с NULL идентификаторами автоматически присваивалось следующее доступное значение. PostgreSQL также не распознаетAUTOINCREMENT
команды, поэтому их необходимо удалить.Вы также захотите проверить наличие
datetime
столбцов в схеме SQLite и изменить ихtimestamp
на PostgreSQL. (Спасибо Клею за указание на это.)Если у вас есть логические значения в вашем SQLite, вы можете преобразовать
1
и0
в1::boolean
и0::boolean
(соответственно) или вы можете изменить логический столбец на целое число в разделе схемы дампа, а затем исправить их вручную внутри PostgreSQL после импорта.Если у вас есть большие двоичные объекты в вашем SQLite, вы захотите настроить схему для использования
bytea
. Вероятно, вам также понадобится смешать несколькоdecode
вызовов . Написание быстрого и грязного копировального аппарата на вашем любимом языке может быть проще, чем переделывать SQL, если вам нужно иметь дело с большим количеством больших двоичных объектов.Как обычно, если у вас есть внешние ключи, вы, вероятно, захотите изучить,
set constraints all deferred
чтобы избежать проблем с порядком вставки, поместив команду в пару BEGIN / COMMIT.Спасибо Nicolas Riley за заметки о логических значениях, blob и ограничениях.
Если у вас есть
`
код, созданный некоторыми клиентами SQLite3, вам необходимо удалить их.PostGRESQL также не распознает
unsigned
столбцы, поэтому вы можете отказаться от него или добавить настраиваемое ограничение, например следующее:CREATE TABLE tablename ( ... unsigned_column_name integer CHECK (unsigned_column_name > 0) );
В то время как SQLite по умолчанию использует нулевые значения
''
, PostgreSQL требует, чтобы они были установлены какNULL
.Синтаксис файла дампа SQLite в основном совместим с PostgreSQL, поэтому вы можете исправить несколько вещей и скормить их
psql
. Импорт большого количества данных через SQL INSERT может занять некоторое время, но это сработает.источник
datetime
столбцы sqlite , вы должны изменить их наtimestamp
для postgres.BLOB
наBYTEA
( stackoverflow.com/questions/3103242 ), изменение 0/1 дляBOOLEAN
столбцов на '0' / '1' и отсрочка ограничений (DEFERRABLE
/SET CONSTRAINTS ALL DEFERRED
).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';
как состояние документации . Затем я создал
testdb
сcreatedb
:createdb testdb
Я выполнил такую
pgloader
команду:pgloader command
а затем подключился к новой базе данных:
psql testdb
После нескольких запросов для проверки данных выяснилось, что все работает достаточно хорошо. Я знаю, что если бы я попытался запустить один из этих скриптов или выполнить пошаговое преобразование, упомянутое здесь, я бы потратил гораздо больше времени.
Чтобы доказать эту концепцию, я сбросил это
testdb
и импортировал в среду разработки на производственном сервере, и данные были переданы без проблем.источник
Я написал сценарий
sqlite3
дляpostgres
миграции. Он не обрабатывает все переводы схемы / данных, упомянутые в https://stackoverflow.com/a/4581921/1303625 , но он делает то, что мне нужно. Надеюсь, это станет хорошей отправной точкой для других.https://gist.github.com/2253099
источник
Сиквел камень (библиотека Ruby) предлагает копирования данных в различных базах данных: http://sequel.jeremyevans.net/rdoc/files/doc/bin_sequel_rdoc.html#label-Copy+Databases
Сначала установите Ruby, затем установите гем, запустив
gem install sequel
.В случае sqlite это будет так:
sequel -C sqlite://db/production.sqlite3 postgres://user@localhost/db
источник
pgloader
.Вы можете использовать однострочник, вот пример с помощью команды 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'
sed -e 's/TINYINT(1)/SMALLINT/g'
- и для сравнения всех типов данных см. stackoverflow.com/questions/1942586/…' | sed -e '
на;
:)Я пробовал редактировать / выполнять регулярное выражение дампа sqlite, поэтому PostgreSQL принимает его, это утомительно и подвержено ошибкам.
Что мне нужно, чтобы работать очень быстро:
Сначала воссоздайте схему в PostgreSQL без каких-либо данных, либо отредактировав дамп, либо, если вы использовали ORM, вам может повезти, и он общается с обоими внутренними компонентами (sqlalchemy, peewee, ...).
Затем перенесите данные с помощью панд. Предположим, у вас есть таблица с полем bool (которое равно 0/1 в sqlite, но должно быть t / f в PostgreSQL)
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 (даже графически с помощью инструмента администрирования), с той лишь оговоркой, что вы должны загрузить таблицы с внешними ключами после того, как вы загрузили таблицы с соответствующими исходными ключами. У меня не было случая круговой зависимости, я думаю, вы можете временно приостановить проверку ключа, если это так.
источник
pgloader творит чудеса при преобразовании базы данных из sqlite в postgresql.
Вот пример преобразования локального sqlitedb в удаленный PostgreSQL db:
pgloader sqlite.db postgresql: // имя пользователя : пароль @ имя хоста / имя базы данных
источник
KABOOM! Control stack exhausted (no more space for function call frames).