加载数据转储时,将 Django 项目从 sqlite3 后端切换到 postgresql 失败

Posted

技术标签:

【中文标题】加载数据转储时,将 Django 项目从 sqlite3 后端切换到 postgresql 失败【英文标题】:Switching Django project from sqlite3 backend to postgresql failes when loading datadump 【发布时间】:2011-03-05 20:25:41 【问题描述】:

我目前正在使用 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"
这难道不是将数据从一个数据库移动到另一个数据库的正确方法吗? 我应该怎么做才能安全地切换数据库后端?

【问题讨论】:

我忽略了一些 django 表。 ./manage.py dumpdata -e sessions -e admin -e contenttypes -e auth.Permission -e authtoken --natural > db.json 然后做了./manage.py loaddata db.json。也许它可以帮助某人。详情看这个问题***.com/questions/853796/… 【参考方案1】:

问题只是您获得了两次定义的内容类型 - 一次是在您执行 syncdb 时,一次来自您尝试导入的导出数据。由于您的数据库中可能还有其他项目依赖于原始内容类型定义,因此我建议您保留这些项目。

因此,在运行 syncdb 之后,执行 manage.py dbshell 并在您的数据库中执行 TRUNCATE django_content_type; 以删除所有新定义的内容类型。那么你不应该有任何冲突——无论如何,在过程的那一部分。

【讨论】:

谢谢,这似乎已经成功了。现在我需要弄清楚的是,为什么 python 解释器在执行涉及 django-tagging 的查询时会转储核心...... 就我而言,postgres 抱怨由于外键约束而无法执行截断,并建议添加 CASCADE 参数,该参数有效。所以:“TRUNCATE django_content_type CASCADE;” 就我而言,我必须TRUNCATE django_content_type CASCADE;,但效果很好! @DanielRoseman 我仍然得到重复的键值:django.db.utils.IntegrityError: Problem installing fixture 'C:\myproject\dump.json': Could not load Authentication.Profile(pk=368): duplicate key value violates unique constraint "Authentication_profile_user_id_key" DETAIL: Key (user_id)=(720) already exists. @DanielRoseman 现在我通过运行这个程序摆脱了以前的错误:python manage.py dumpdata --natural-foreign --natural-primary -e auth.Permission --indent 4 > datadump.json) 但现在我又遇到了另一个错误:DETAIL: Key (user_id)=(1) already exists. 请帮助 :(【参考方案2】:

Django ticket 7052 上有一个关于它的大讨论。现在正确的做法是使用--natural参数,例如:./manage.py dumpdata --natural --format=xml --indent=2 > fixture.xml

为了使--natural 与您的模型一起使用,它们必须实现natural_keyget_by_natural_key,如the Django documentation regarding natural keys 所述。

话虽如此,您可能仍需要在使用./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

【讨论】:

以上是关于加载数据转储时,将 Django 项目从 sqlite3 后端切换到 postgresql 失败的主要内容,如果未能解决你的问题,请参考以下文章

如何使用现有模型和迁移恢复 Django 项目的转储数据库备份?

不支持按文件名导入

转储数据集时将数据从 Hive 加载到 Pig 错误

为还没有任何迁移的 Django 项目创建迁移

Python:可以转储数据无法加载数据。 Unicode解码错误

将 bigquery JSON 数据转储加载到 R tibble