Перенос проекта Django из бэкэнда sqlite3 в postgresql при загрузке datadump

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

Я использовал ./manage.py dumpdata > dump.json для создания дампа данных и изменил свои настройки, чтобы использовать postgresql. Попытка сначала с пустой базой данных сделать ./manage.py loaddata dump.json привела к ошибкам о не существующих таблицах, поэтому я запустил ./manage.py syncdb и попробовал еще раз. Это приводит к ошибке:

Problem installing fixture 'dump.json': Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/django/core/management/commands/loaddata.py", line 163, in handle
    obj.save()
  File "/usr/lib/python2.6/site-packages/django/core/serializers/base.py", line 163, in save
    models.Model.save_base(self.object, raw=True)
  File "/usr/lib/python2.6/site-packages/django/db/models/base.py", line 495, in save_base
    rows = manager.filter(pk=pk_val)._update(values)
  File "/usr/lib/python2.6/site-packages/django/db/models/query.py", line 448, in _update
    return query.execute_sql(None)
  File "/usr/lib/python2.6/site-packages/django/db/models/sql/subqueries.py", line 124, in execute_sql
    cursor = super(UpdateQuery, self).execute_sql(result_type)
  File "/usr/lib/python2.6/site-packages/django/db/models/sql/query.py", line 2347, in execute_sql
    cursor.execute(sql, params)
  File "/usr/lib/python2.6/site-packages/django/db/backends/util.py", line 19, in execute
    return self.cursor.execute(sql, params)
IntegrityError: duplicate key value violates unique constraint "django_content_type_app_label_key"
  • Не правильный ли перенос данных из одной базы данных в другую?
  • Что мне делать, чтобы безопасно переключаться на БД сервера?

Ответы

Ответ 1

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

Итак, после запуска syncdb выполните manage.py dbshell и в вашей базе данных выполните TRUNCATE django_content_type;, чтобы удалить все вновь определенные типы контента. Тогда вы не должны иметь никаких конфликтов - в той части процесса, в любом случае.

Ответ 2

Существует большое обсуждение этого вопроса в Django ticket 7052. Правильный путь теперь - использовать параметр --natural, например: ./manage.py dumpdata --natural --format=xml --indent=2 > fixture.xml

Чтобы --natural работал с вашими моделями, они должны реализовать natural_key и get_by_natural_key, как описано в документации Django относительно натуральных ключей.

Сказав это, вам все равно придется редактировать данные перед импортом с помощью ./manage.py loaddata. Например, если ваши приложения изменились, syncdb заполнит таблицу django_content_type, и вы можете удалить соответствующие записи из xml файла перед загрузкой.

Ответ 3

Это сработало для меня. Вероятно, вы хотите, чтобы сервер был остановлен, поэтому новые данные не теряются. Дамп:

$ python manage.py dumpdata --exclude auth.permission --exclude contenttypes --natural > db.json

Убедитесь, что ваши модели не имеют сигналов (например, post_save) или всего, что создает модели. Если вы это сделаете, прокомментируйте это на мгновение.

Измените settings.py, чтобы указать на новую базу данных и настроить ее:

$ python manage.py syncdb

$ python manage.py migrate

Загрузите данные:

./manage.py loaddata db.json