Django: Каковы наилучшие методы миграции проекта из sqlite в PostgreSQL
Мне нужно перенести сложный проект из sqlite в PostgreSQL.
У многих людей проблема с внешними ключами, усечение данных и т.д....
- Есть ли полная автоматическая утилита?
- Нужно ли проверять некоторые данные или схему перед переносом?
Изменить: я пробовал django-command-extensions DumpScript, но он не работает на моем
2 ГБ оперативной памяти с текущим DataSet.
Ответы
Ответ 1
По моему опыту, сбрасывание и восстановление из SQL не работает должным образом.
Вместо этого выполните следующие действия:
1. Содержимое dump db для json
$ ./manage.py dumpdata > dump.json
2. Переключите бэкэнд в settings.py
DATABASES = {
# COMMENT OUT:
# 'default': dj_database_url.config(default='sqlite:////full/path/to/your/database/file.sqlite'),
# ADD THIS INSTEAD:
'default': dj_database_url.config(default='postgres://localhost:5432/postgres_db_name'),
}
3. Syncdb и перенести новую БД в ту же структуру таблицы
$ ./manage.py syncdb
$ ./manage.py migrate
4. Загрузите json в новый db.
$ ./manage.py loaddata dump.json
5. Congrats! Теперь новые данные находятся в вашем postgres db.
Ответ 2
Ниже приводится уточнение ответа Нимо и ответ Стивена для Django 1.7 +:
-
./manage.py dumpdata --natural-primary --natural-foreign > dump.json
- Измените
DATABASES
в settings.py
, чтобы указать на новый (PostgreSQL) db.
-
./manage.py migrate
-
./manage.py loaddata dump.json
Одна из проблем, с которыми я столкнулась, заключается в том, что SQLite, похоже, фактически не обеспечивает максимальную длину для CharField
s. В моем случае это сделало шаг loaddata
неудачным. Мне удалось найти (и удалить) экземпляры модели со слишком длинными значениями CharField
с помощью:
MyModel.objects.extra(where=["LENGTH(text) > 20"]).delete()
Как только я сделал это до шага 1. выше, все сработало.
Ответ 3
Мне никогда не приходилось это делать, но я бы попробовал.
- Остановить работу серверов
- python manage.py dumpdatali >
- Измените settings.py, чтобы указать на недавно созданную базу данных postgres
- python manage.py loaddatali >
Ответ 4
Другим способом сделать это может быть использование нескольких баз данных.
http://docs.djangoproject.com/en/dev/topics/db/multi-db/
Важно, чтобы вы прочитали этот раздел.
http://docs.djangoproject.com/en/dev/topics/db/multi-db/#moving-an-object-from-one-database-to-another
Из того, что я понимаю, это означает, что если в вашей новой базе данных нет данных, из светильников, например, вы могли бы сделать
queryset = MyModel.objects.using("old-db").all()
for obj in queryset:
obj.save(using="new-db")
Поскольку это должно сохранить первичные ключи, я не думаю, что возникнут какие-либо проблемы с внешним ключом.
Ответ 5
Согласно ответу @Nimo, используемому из "syncdb"
, "syncdb"
не работает в Django 1.9 и более поздних версиях (это работает в Django 1.7)
Вместо этого используйте команду ниже:
python manage.py migrate
И настройка конфигурации Postgres здесь:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
Ответ 6
Прежде всего, я просто попробую просто:
sqlite3 sqllitedb .dump | psql postgresdb
В этот момент просто проверьте это. Напишите несколько тестовых скриптов в Django для вывода набора выборочных записей для каждого приложения, а затем выполните diff, чтобы убедиться, что они идентичны. Если они есть, то ваше преобразование, вероятно, прекрасно.
Если это не работает...
Я бы рекомендовал не использовать Django для дампа и загрузки данных, так как я предполагаю, что он не оптимизирован для этого.
Вместо этого я бы создал вторую версию вашего приложения с правильными настройками базы данных PostgreSQL, запустил syncdb для создания всех таблиц, а затем скопировал данные из mysqllite в PostgreSQL с помощью другого инструмента.
Дело в том, что большинство проблем при преобразовании данных в определения таблиц и т.д. Это, по-видимому, самое необычное. Если вы можете создать SQL script, который является дампом только содержимого таблицы, это должно быть довольно стандартными командами SQL INSERT INTO
.
Честно говоря, я не понимаю, почему возникнут проблемы с иностранным ключом. Предполагая, что sqlite создает точные внешние ключи (и почему бы и нет?), Тогда нет способа, который бы не копировал правильно. Действительно, внешние ключи не являются особыми формами данных. Не более вероятно, что поле UserProfile.user_id
будет содержать неправильное значение, чем поле UserProfile.photo
. Если внешний вопрос состоит в том, что сами поля неправильно идентифицированы как поля внешнего ключа (т.е. Никаких ограничений), тогда проблема с первым созданием базы данных с использованием syncdb
будет решать эту проблему.
В соответствии с усечением: как я понимаю, PostgreSQL выдает жесткую ошибку, если данные будут усечены. Я не знаю, так ли это в случае с sqlite или если он просто усекает молча. В любом случае, опять же, предполагая, что sqlite не каким-то образом перетаскивает данные на экспорт, поля должны содержать данные, которые являются надлежащей длиной для поля, в котором он находится. Единственное, что я могу думать об этом, может повлиять на это кодирование символов, поэтому make что поля PostgreSQL имеют одинаковую кодировку, как это делают таблицы sqlite, по крайней мере во время импорта.
Ответ 7
Что мне помогло, так это запустить сиквел от ruby. Просто запустите команду:
gem install sequel
Вам необходимо установить в своей системе пакеты devel для postgres, sqlite и ruby. Запустите команду:
gem install pg sqlite3
Создайте пустую базу данных на postgresql, скажем, testDB и назначьте разрешение на предоставление пользователю. Из командной строки запустите:
sequel -C sqlite:///path/to/sqlitedb.db postgres://user:[email protected]/testDB
Это будет работать без ошибок.
Измените настройки в вашем проекте django для работы с базой данных postgres.
./manage migrate (not necessary)
Запустите сервер