Django: Каковы лучшие практики для миграции проекта из sqlite в PostgreSQL - PullRequest
24 голосов
/ 13 августа 2010

Мне нужно перенести сложный проект из sqlite в PostgreSQL. У многих людей проблемы с внешними ключами, усечением данных и т. Д. ...

  • Есть ли полностью автоматизированная утилита?
  • Нужно ли проверять некоторые данные или схему перед миграцией?

Редактировать : я пытался django-расширения команд DumpScript , но он не работает 2 ГБ ОЗУ с моим текущим набором данных.

Ответы [ 7 ]

32 голосов
/ 08 декабря 2014

По моему опыту, дамп и восстановление из SQL не работает должным образом.

Вместо этого вы должны следовать этой последовательности:

1.Записать содержимое базы данных в 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.Синхронизируйте и перенесите новую БД в ту же структуру таблицы

$ ./manage.py syncdb
$ ./manage.py migrate

4.Загрузите JSON в новую базу данных.

$ ./manage.py loaddata dump.json

5.Congrats!Теперь новые данные в вашем postgres db.

16 голосов
/ 12 мая 2017

Ниже приводится уточнение ответа Нимо и ответа Стивена для Джанго 1,7 +:

  1. ./manage.py dumpdata --natural-primary --natural-foreign > dump.json
  2. ИзменитьDATABASES в settings.py для указания на новую (PostgreSQL) базу данных.
  3. ./manage.py migrate
  4. ./manage.py loaddata dump.json

Одна проблема, с которой я столкнулся, заключается в том, чтоSQLite, похоже, на самом деле не обеспечивает максимальную длину CharField с.В моем случае это привело к сбою шага loaddata.Мне удалось найти (и удалить) экземпляры модели со слишком длинными значениями CharField с помощью:

MyModel.objects.extra(where=["LENGTH(text) > 20"]).delete()

Как только я сделал это до шага 1. выше, все работало.

9 голосов
/ 13 августа 2010

Мне никогда не приходилось это делать, но я бы попробовал:

  1. Остановить работу серверов
  2. python manage.py dumpdata
  3. Изменить настройки.py, чтобы указать на вновь созданную базу данных postgres
  4. python manage.py loaddata
4 голосов
/ 19 августа 2010

Другим способом сделать это может быть использование нескольких баз данных.

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")

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

2 голосов
/ 21 февраля 2018

Согласно ответу @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': '',
    }
}
2 голосов
/ 13 августа 2010

Перво-наперво, я бы попробовал просто:

sqlite3 sqllitedb .dump | psql postgresdb

В этот момент просто протестируйте его.Напишите несколько тестовых сценариев в Django, чтобы вывести набор образцов записей для каждого приложения, а затем выполните diff, чтобы убедиться, что они идентичны.Если это так, то ваше преобразование, вероятно, в порядке.

Если это не сработает ...

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

Вместо этого я бы создал вторую версию вашего приложения с правильными настройками базы данных PostgreSQL, запустил syncdb для создания всех таблиц, а затем скопировал данные из mysqllite в PostgreSQLиспользуя какой-то другой инструмент.

Дело в том, что большинство проблем при преобразовании данных заключается в определениях таблиц и т. д. Они кажутся наиболее специфическими.Если вы можете сгенерировать сценарий SQL, который представляет собой дамп только содержимого таблицы, то это должны быть довольно стандартные команды SQL INSERT INTO.

Честно говоря, я не понимаю, почему могут возникнуть проблемы с внешним ключом.Если предположить, что sqlite создает точные внешние ключи (а почему бы и нет?), То нет способа, который бы правильно копировал.Действительно, внешние ключи не являются специальными формами данных.Скорее всего, поле UserProfile.user_id будет содержать неправильное значение, чем поле UserProfile.photo.Если проблема с внешним ключом заключается в том, что сами поля неправильно определены как поля внешнего ключа (то есть без ограничений), то вариант первого создания базы данных с использованием syncdb решит эту проблему.

Согласноусечение: насколько я понимаю, PostgreSQL выдает серьезную ошибку, если данные собираются урезать.Я не знаю, так ли это с sqlite или он просто усекается молча.В любом случае, опять-таки, предполагая, что sqlite каким-то образом не манипулирует данными при экспорте, поля должны содержать данные, которые имеют правильную длину для поля, в которое они входят. Единственное, что я могу подумать, это может повлиять на это - кодировка символов, поэтомуубедитесь, что поля PostgreSQL имеют ту же кодировку, что и таблицы sqlite, по крайней мере во время импорта.

1 голос
/ 18 июля 2018

Что мне помогло, так это запустить сиквел от ruby.Просто запустите команду:

gem install sequel

Вам потребуется установить в своей системе пакеты devel для postgres, sqlite и ruby. Выполнить команду:

gem install pg sqlite3

Создать пустую базу данных вpostgresql, скажем, testDB и назначить пользователю разрешение на предоставление доступа. Из командной строки запустите:

sequel -C sqlite:///path/to/sqlitedb.db postgres://user:password@host/testDB

Это запустится без ошибок.

Измените настройки в вашем проекте django, чтобы они работалис базой данных postgres Запустите

./manage migrate (not necessary)

Запустите сервер

...