改变Django中的数据库表

时间:2008-08-30 14:36:39

标签: database django

我正在考虑将Django用于我正在开始的项目(fyi,一个基于浏览器的游戏),我最喜欢的一个功能是使用syncdb自动创建基于数据库的表在我定义的Django模型上(我似乎无法在任何其他框架中找到的功能)。 当我在documentation

中看到这个时,我一直在想这太好了
  

Syncdb不会改变现有的表

     

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

     

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

似乎改变现有的表格必须“手工”完成。

我想知道的是最好的方法。我想到了两个解决方案:

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

有什么想法吗?

7 个答案:

答案 0 :(得分:59)

手动执行SQL更改和转储/重新加载都是选项,但您可能还想查看Django的一些架构演变包。最成熟的选项是django-evolutionSouth

编辑:嘿,来dmigrations

更新:由于此答案最初编写,django-evolutiondmigrations都停止了主动开发,South已成为架构的事实标准在Django迁移。南方的部分地区甚至可以在下一个或两个版本中集成到Django中。

更新:基于South的架构迁移框架(由South的作者Andrew Godwin撰写)包含在Django 1.7 +中。

答案 1 :(得分:16)

如同同一主题的其他答案所述,请务必观看YouTube上的DjangoCon 2008 Schema Evolution Panel

此外,地图上有两个新项目:SimplemigrationsMigratory

答案 2 :(得分:9)

这样做的一个好方法是通过灯具,尤其是initial_data灯具。

fixture是包含数据库的序列化内容的文件集合。所以就像拥有数据库的备份一样,但是Django知道它更容易使用,并且当你来做单元测试时会有额外的好处。

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

您可以使用django-admin.py loaddata加载修正,但更重要的是,如果您的灯具名称为initial_data.json,当您执行syncdb时,它会自动加载,从而节省了导入的麻烦你自己。

另一个好处是,当您运行manage.py test来运行单元测试时,临时测试数据库也会加载初始数据夹具。

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

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

答案 3 :(得分:4)

我一直在使用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)
    ]

如果我有更多的指纹和变化,我会重新考虑它。在此之前,让它更清洁会从其他东西中窃取开发时间。

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

答案 4 :(得分:3)

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

答案 5 :(得分:2)

到目前为止,在我的公司,我们使用了手动方法。什么最适合你取决于你的发展风格。

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

这对我们来说非常有效。让它全部自动化是一个利基愿景,但对我们来说很难 - 也许我们可以管理迁移,但我们仍然需要处理额外的库,服务器,无论依赖性。

答案 6 :(得分:2)

Django 1.7(目前正在开发中)是adding native support,用于manage.py migratemanage.py makemigrationsmigrate弃用syncdb)的架构迁移。