加载数据转储时,将 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_key
和get_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 项目的转储数据库备份?