30

我需要将一个复杂的项目从 sqlite 迁移到 PostgreSQL。很多人似乎有外键、数据截断等问题......

  • 有全自动实用程序吗?
  • 迁移前是否需要检查一些数据或架构?

编辑:我尝试了 django-command-extensions DumpScript,但它不能在我的 2GB RAM PC 上使用我当前的 DataSet 运行。

4

7 回答 7

38

根据我的经验,从 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. 同步db并将新DB迁移到同一个表结构

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

4. 将 json 加载到新的数据库中。

$ ./manage.py loaddata dump.json

5. 恭喜!现在新数据在您的 postgres 数据库中。

于 2014-12-08T14:02:58.150 回答
23

以下是对Nimo 的回答Stephen对 Django 1.7+ 的回答的改进:

  1. ./manage.py dumpdata --natural-primary --natural-foreign > dump.json
  2. 更改DATABASESsettings.py指向新的 (PostgreSQL) 数据库。
  3. ./manage.py migrate
  4. ./manage.py loaddata dump.json

我遇到的一个问题是 SQLite 似乎并没有真正强制CharFields 的最大长度。就我而言,这使该loaddata步骤失败。我能够通过以下方式找到(并删除)具有太长CharField值的模型实例:

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

一旦我在上面的步骤 1. 之前这样做了,一切正常。

于 2017-05-12T12:36:59.287 回答
9

我从来没有这样做过,但我会尝试的是。

  1. 停止运行服务器
  2. python manage.py 转储数据
  3. 更改 settings.py 以指向新创建的 postgres 数据库
  4. python manage.py 加载数据
于 2010-08-13T13:08:10.457 回答
6

根据@Nimo的回答,使用 from ,在Django 1.9"syncdb"及更高版本中不起作用(适用于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': '',
    }
}
于 2018-02-21T13:22:04.867 回答
4

另一种方法可能是使用多个数据库。

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

因为这应该保留主键,所以我认为不会有任何外键问题。

于 2010-08-19T13:15:05.717 回答
3

对我有用的是从 ruby​​ 运行续集。只需运行命令:

gem install sequel

您需要在系统上安装 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)

运行服务器

于 2018-07-18T12:59:39.037 回答
2

首先我会尝试一个简单的:

sqlite3 sqllitedb .dump | psql postgresdb

到那时,只需测试一下。在 Django 中编写一些测试脚本,为每个应用程序输出一组示例记录,然后进行 diff 以确保它们相同。如果是,那么您的转换可能没问题。

如果这不起作用...

我建议不要使用 Django 来转储和加载数据,因为我猜它没有经过优化。

相反,我会使用正确的 PostgreSQL 数据库设置创建您的应用程序的第二个版本,运行 syncdb 以创建所有表,然后使用其他工具将数据从 mysqllite 复制到 PostgreSQL。

问题是,转换数据时的大多数问题都存在于表定义等中。这些似乎是最特殊的。如果您可以生成一个仅转储表内容的 SQL 脚本,那应该是非常标准的 SQLINSERT INTO命令。

老实说,我不明白为什么会有外键问题。假设 sqlite 正在创建准确的外键(为什么不呢?),那么就没有办法不能正确复制。实际上,外键不是特殊形式的数据。与UserProfile.user_id字段相比,字段包含错误值的可能性UserProfile.photo不大。如果外键问题是字段本身没有被正确识别为外键字段(即没有约束),那么首先使用创建数据库的选项syncdb将解决该问题。

根据截断:据我了解,如果数据即将被截断,PostgreSQL 会抛出一个硬错误。我不知道 sqlite 是否是这种情况,或者它是否只是默默地截断。无论哪种方式,再次假设 sqlite 没有以某种方式在导出时修改数据,这些字段应该包含的数据是它要进入的字段的正确长度。我能想到的唯一可能会影响这一点的是字符编码,所以让确保 PostgreSQL 字段具有与 sqlite 表相同的编码,至少在导入期间是这样。

于 2010-08-13T15:00:39.937 回答