代码之家  ›  专栏  ›  技术社区  ›  Pierre-Jean Coudert

Django:将项目从sqlite迁移到PostgreSQL的最佳实践是什么

  •  23
  • Pierre-Jean Coudert  · 技术社区  · 14 年前

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

    • 有全自动的公用设施吗?
    • 迁移之前需要检查一些数据或架构吗?

    编辑 :我试过了 django-command-extensions DumpScript 但它不会影响我的 2GB RAM PC和我当前的数据集。

    7 回复  |  直到 7 年前
        1
  •  35
  •   Nimo    10 年前

    以我的经验,从SQL中转储和还原无法正常工作。

    您应该改为遵循以下顺序:

    一。将数据库内容转储到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'),
    }
    

    三。同步数据库并将新数据库迁移到同一表结构

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

    四。将json加载到新的db。

    $ ./manage.py loaddata dump.json
    

    5个。恭喜!现在新数据在postgres数据库中。

        2
  •  17
  •   Community CDub    8 年前

    以下是对 Nimo's answer Stephen's answer 对于Django 1.7+:

    1. ./manage.py dumpdata --natural-primary --natural-foreign > dump.json
    2. 改变 DATABASES 在里面 settings.py 指向新的(PostgreSQL)数据库。
    3. ./manage.py migrate
    4. ./manage.py loaddata dump.json

    我遇到的一个问题是SQLite似乎并没有强制执行最大长度。 CharField s、 在我的情况下,这使得 loaddata 步进失败。我发现(和删除)模型实例的时间太长 查菲尔德 值通过:

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

    有一次我在第一步之前做了这个。上面,一切正常。

        3
  •  9
  •   Stephen Paulger    14 年前

    我从来没有做过,但我会尝试。

    1. 停止运行服务器
    2. python manage.py转储数据
    3. Alter settings.py指向新创建的postgres数据库
    4. python manage.py加载数据
        4
  •  4
  •   Stephen Paulger    14 年前

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

    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

    据我所知,这意味着如果您的新数据库中没有数据,例如您可以从fixture中

    queryset = MyModel.objects.using("old-db").all()
    for obj in queryset:
        obj.save(using="new-db")
    

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

        5
  •  3
  •   Benyamin Jafari    5 年前

    根据@Nimo的回答,从 "syncdb" , “同步数据库” 不适用于 姜戈1.9 以后(这就行了 姜戈1.7 )

    相反,请使用下面的命令:

    python manage.py migrate


    Postgres设置配置如下:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'myproject',
            'USER': 'myprojectuser',
            'PASSWORD': 'password',
            'HOST': 'localhost',
            'PORT': '',
        }
    }
    
        6
  •  2
  •   Jordan Reiter    14 年前

    sqlite3 sqllitedb .dump | psql postgresdb
    

    在这一点上,只要测试一下。在Django中编写一些测试脚本,为每个应用程序输出一组样本记录,然后执行diff以确保它们是相同的。如果他们是,那么你的转换可能是好的。

    如果那不起作用。。。

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

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

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

    老实说,我不明白为什么会有外键问题。假设sqlite正在创建准确的外键(为什么不呢?)那就不可能复制不正确了。实际上,外键不是特殊形式的数据。不太可能 UserProfile.user_id 字段将包含不正确的值 UserProfile.photo 菲尔德会的。如果外键问题是字段本身没有正确地标识为外键字段(即没有约束),那么可以选择首先使用 syncdb 会解决这个问题。

    根据截断:据我所知,如果数据即将被截断,PostgreSQL会抛出一个硬错误。我不知道sqlite是这样的,还是它只是无声地截断。不管怎样,再次假设sqlite在导出时并没有以某种方式修改数据,那么字段应该包含的数据对于它要进入的字段来说是合适的长度。我唯一能想到的可能影响这一点的是字符编码,所以请确保PostgreSQL字段的编码与sqlite表的相同,至少在导入期间是这样。

        7
  •  1
  •   abitran    6 年前

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

    gem install sequel
    

    您需要在系统上安装postgres、sqlite和ruby的devel包 运行命令:

    gem install pg sqlite3
    

    在postgresql上创建一个空数据库,比如testDB,并为用户分配一个grant权限 从命令提示符运行:

    sequel -C sqlite:///path/to/sqlitedb.db postgres://user:password@host/testDB
    

    运行时不会出错。

    更改django项目中的设置以使用postgres数据库 跑步

    ./manage migrate (not necessary)

    运行服务器