English 中文(简体)
改变Django中的数据库表
原标题:
  • 时间:2008-08-30 14:36:39
  •  标签:

I m considering using Django for a project I m starting (fyi, a browser-based game) and one of the features I m liking the most is using syncdb to automatically create the database tables based on the Django models I define (a feature that I can t seem to find in any other framework). I was already thinking this was too good to be true when I saw this in the documentation:

Syncdb不会更改现有表

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

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

看来,修改现有的表格将不得不“手工”完成。

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

  • As the documentation suggests, make the changes manually in the DB;
  • Do a backup of the database, wipe it, create the tables again (with syncdb, since now it s creating the tables from scratch) and import the backed-up data (this might take too long if the database is big)

有什么想法吗?

最佳回答

如同一主题的其他答案所述,请务必观看DjangCon 2008架构演进面板在YouTube上。

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

问题回答

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

编辑:嘿,来了d迁移

更新:由于此答案最初是编写的,django进化数据迁移已停止主动开发,并且South已经成为Django中模式迁移的事实标准。South的部分内容甚至可能在下一两个版本中集成到Django。

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

实现这一点的一个好方法是通过fixture,特别是initial_datafixture。

fixture是包含数据库的序列化内容的文件集合。因此,这就像有一个数据库备份,但Django意识到这一点,它更容易使用,并且在进行单元测试等操作时会有额外的好处。

您可以使用<code>django-admin.py dumppdatea</code>从当前数据库中的数据创建fixture。默认情况下,数据采用JSON格式,但也可以使用XML等其他选项。存储fixture的好地方是应用程序目录的fixture子目录。

您可以使用django-admin.py loaddata加载fixture,但更重要的是,如果您的fixture的名称类似于initial_data.json,那么当您执行syncdb时,它将自动加载,从而省去您自己导入它的麻烦。

另一个好处是,当您运行<code>manage.py test</code>来运行单元测试时,临时测试数据库也将加载初始数据固定装置。

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

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

我一直在使用django进化。注意事项包括:

  • Its automatic suggestions have been uniformly rotten; and
  • Its fingerprint function returns different values for the same database on different platforms.

也就是说,我发现自定义<code>schema_eevolution.py</code>方法很方便。要解决指纹问题,我建议使用以下代码:

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 makemigration添加对架构迁移的本机支持migrate弃用syncdb)。





相关问题
热门标签