加载datadump时,将Django项目从sqlite3后端切换到postgresql failes

时间:2010-06-19 19:27:55

标签: django postgresql sqlite

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

3 个答案:

答案 0 :(得分:33)

问题很简单,就是您要定义两次内容类型 - 一次是syncdb,一次是您尝试导入的导出数据。由于您的数据库中可能还有其他依赖于原始内容类型定义的项目,因此我建议您保留这些项目。

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

答案 1 :(得分: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文件中删除相应的条目。

答案 2 :(得分:0)

这对我有用。您可能希望确保服务器已停止,因此不会丢失新数据。转储它:

$ 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