题
我正在考虑将 Django 用于我正在启动的一个项目(仅供参考,一个基于浏览器的游戏),我最喜欢的功能之一是使用 syncdb
根据我定义的 Django 模型自动创建数据库表(我似乎在任何其他框架中都找不到该功能)。当我在网上看到这个时,我已经在想这太好了,难以置信。 文档:
Syncdb 不会更改现有表
syncdb 只会为尚未安装的模型创建表。它永远不会发出 ALTER TABLE 语句来匹配安装后对模型类所做的更改。对模型类和数据库模式的更改通常会涉及某种形式的歧义,在这些情况下,Django 必须猜测要进行的正确更改。在此过程中存在丢失关键数据的风险。
如果您对模型进行了更改并希望更改数据库表以匹配,请使用 sql 命令显示新的 SQL 结构并将其与现有表模式进行比较以计算出更改。
似乎更改现有表必须“手动”完成。
我想知道的是做到这一点的最佳方法。我想到了两种解决方案:
- 正如文档所建议的,在数据库中手动进行更改;
- 备份数据库,擦除它,再次创建表(使用syncdb,因为现在它从头开始创建表)并导入备份的数据(如果数据库很大,这可能需要很长时间)
有任何想法吗?
解决方案
正如同一主题的其他答案中所述,请务必观看 DjangoCon 2008 模式演变面板 在YouTube上。
其他提示
做到这一点的一个好方法是通过固定装置,特别是 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 migrate
和 manage.py makemigrations
(migrate
不赞成 syncdb
).