我正在考虑将 Django 用于我正在启动的一个项目(仅供参考,一个基于浏览器的游戏),我最喜欢的功能之一是使用 syncdb 根据我定义的 Django 模型自动创建数据库表(我似乎在任何其他框架中都找不到该功能)。当我在网上看到这个时,我已经在想这太好了,难以置信。 文档:

Syncdb 不会更改现有表

syncdb 只会为尚未安装的模型创建表。它永远不会发出 ALTER TABLE 语句来匹配安装后对模型类所做的更改。对模型类和数据库模式的更改通常会涉及某种形式的歧义,在这些情况下,Django 必须猜测要进行的正确更改。在此过程中存在丢失关键数据的风险。

如果您对模型进行了更改并希望更改数据库表以匹配,请使用 sql 命令显示新的 SQL 结构并将其与现有表模式进行比较以计算出更改。

似乎更改现有表必须“手动”完成。

我想知道的是做到这一点的最佳方法。我想到了两种解决方案:

  • 正如文档所建议的,在数据​​库中手动进行更改;
  • 备份数据库,擦除它,再次创建表(使用syncdb,因为现在它从头开始创建表)并导入备份的数据(如果数据库很大,这可能需要很长时间)

有任何想法吗?

有帮助吗?

解决方案

正如同一主题的其他答案中所述,请务必观看 DjangoCon 2008 模式演变面板 在YouTube上。

此外,地图上还有两个新项目: 简单迁移迁徙性.

其他提示

手动进行 SQL 更改和转储/重新加载都是选项,但您可能还想查看 Django 的一些模式演化包。最成熟的选择是 Django 进化.

编辑: :嘿,来了 迁徙.

更新: :由于这个答案最初是写的, Django 进化迁徙 都停止了积极的发展并且 已成为 Django 中模式迁移的事实上的标准。South 的部分内容甚至可能会在下一两个版本中集成到 Django 中。

更新: :Django 1.7+ 中包含一个基于 South 的模式迁移框架(由 South 的作者 Andrew Godwin 编写)。

做到这一点的一个好方法是通过固定装置,特别是 initial_data 固定装置。

固定装置是包含数据库序列化内容的文件集合。因此,这就像拥有数据库的备份,但由于 Django 知道它更易于使用,并且当您进行单元测试等操作时,它还会带来额外的好处。

您可以使用数据库中当前的数据创建夹具 django-admin.py dumpdata. 。默认情况下,数据采用 JSON 格式,但也可以使用其他选项,例如 XML。存放固定装置的好地方是 fixtures 您的应用程序目录的子目录。

您可以使用加载夹具 django-admin.py loaddata 但更重要的是,如果您的灯具名称如下 initial_data.json 当您执行以下操作时,它会自动加载 syncdb, ,省去了自己导入的麻烦。

另一个好处是,当你跑步时 manage.py test 为了运行单元测试,临时测试数据库还将加载初始数据夹具。

当然,当您向模型添加属性并向数据库添加列时,这将起作用。如果您从数据库中删除一列,您将需要更新您的装置以删除该列的数据,这可能并不简单。

当在开发过程中进行大量小的数据库更改时,这种方法效果最佳。对于更新生产数据库,手动生成的 SQL 脚本通常效果最好。

我一直在使用 django-evolution。注意事项包括:

  • 它的自动建议已经一律腐烂了。和
  • 其指纹函数对于不同平台上的同一数据库返回不同的值。

也就是说,我发现了这个习惯 schema_evolution.py 方法得心应手。为了解决指纹问题,我建议使用如下代码:

BEFORE = 'fv1:-436177719' # first fingerprint
BEFORE64 = 'fv1:-108578349625146375' # same, but on 64-bit Linux
AFTER = 'fv1:-2132605944' 
AFTER64 = 'fv1:-3559032165562222486'

fingerprints = [
    BEFORE, AFTER,
    BEFORE64, AFTER64,
    ]

CHANGESQL = """
    /* put your SQL code to make the changes here */
    """

evolutions = [
    ((BEFORE, AFTER), CHANGESQL),
    ((BEFORE64, AFTER64), CHANGESQL)
    ]

如果我有更多的指纹和更改,我会重新考虑它。在那之前,让它变得更干净将会从其他方面窃取开发时间。

编辑: 鉴于我无论如何都要手动构建我的更改,我会尝试 迁徙 下次。

django 命令扩展 是一个django库,它为manage.py提供了一些额外的命令。其中之一是 sqldiff,它应该为您提供更新到新模型所需的 sql。然而,它被列为“非常实验性”。

到目前为止,在我的公司我们一直使用手动方法。什么最适合您很大程度上取决于您的开发风格。

我们通常在生产系统中没有太多的模式更改,也没有从开发到生产服务器的正式部署。每当我们推出(每年 10-20 次)时,我们都会对当前和即将到来的生产分支进行填充差异,检查所有代码并注意生产服务器上需要更改的内容。所需的更改可能是附加依赖项、对设置文件的更改以及对数据库的更改。

这对我们来说非常有效。让一切自动化是一个利基愿景,但对我们来说很困难——也许我们可以管理迁移,但我们仍然需要处理额外的库、服务器或任何依赖项。

Django 1.7(目前正在开发中)是 添加本机支持 用于架构迁移 manage.py migratemanage.py makemigrations (migrate 不赞成 syncdb).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top