创建或更改 PostgreSQL 表以确保 Django 模型匹配

Posted

技术标签:

【中文标题】创建或更改 PostgreSQL 表以确保 Django 模型匹配【英文标题】:Create or Alter PostgreSQL Table to ensure Django Models match 【发布时间】:2019-04-19 02:48:34 【问题描述】:

我今天在 Django 项目的开发过程中遇到了一个烦人的问题,我试图在测试数据库和开发数据库之间移动,我似乎无法找到解决迁移问题的可靠方法。

让我们调用我的“测试”数据库:testDB 和我的“开发”数据库:devDB

我像往常一样通过 Django settings.py 访问 testDB,并进行了迁移,添加了您在下面的代码中看到的 clientID 字段。

然后,我决定在我的 Django 的 settings.py 中切换到 devDB 来运行 python manage.py migrate 和我的 clientID 字段未添加到新数据库中。当我运行 python manage.py makemigrations 时,正如预期的那样,“未检测到任何更改”。

请注意,我在进行迁移后使用 PyPi 的 django-reset-migrations 包,因此迁移文件夹不会变得复杂,所有内容都存储在单个 0001_initial.py 迁移文件中。

我没有看到比编写自己的脚本更好的方法来处理这个问题并添加了适当的列,这让我想到了我的问题......

如果我使用:python manage.py sqlmigrate objects 0001(这是我的 0001_initial.py 文件),我会看到以下创建代码:

CREATE TABLE "objects_users" (
    "id" serial NOT NULL PRIMARY KEY, 
    "clientID" integer NOT NULL, 
    "email" varchar(100) NOT NULL, 
    "first_name" varchar(100) NOT NULL, 
    "last_name" varchar(100) NOT NULL, 
    "phone" varchar(100) NOT NULL, 
    "password" varchar(100) NOT NULL, 
    "type" varchar(100) NOT NULL, 
    "date_created" timestamp with time zone NOT NULL, 
    "active" varchar(100) NOT NULL);

我如何使用这个创建语句并循环包含的字段以确保它们在我连接到的数据库中可用(我认为使用 alter 语句是最好的方法)?

大笔记

我只使用 Django 几个月,但我确实记得 Django 的文档说添加属性 null=true 到添加的 Model 通常是一个最佳主意.fields 以便在迁移发生时自动将它们添加到数据库中。我不确定这是否是我的实例中的问题,我只是想找到一个解决方案,该解决方案可以自动确保无论我连接到什么数据库,我都完全同步并且没有 SQL 错误表明字段不存在,即使我运行迁移。

到目前为止,我已经能够解决我的问题,我清除了我连接到的任何数据库,然后根据初始迁移文件运行 python manage.py migrate,但这不是有效的我无法重置所有内容的生产实例的解决方案。

我需要想法,我认为基于我从python manage.py sqlmigrate objects 0001 获得的字符串的 alter table 语句是迄今为止最好的,但我愿意接受任何可以解决我的问题的事情,所以我不必担心这个了。

【问题讨论】:

【参考方案1】:

请注意,我在进行迁移后使用 PyPi 的 django-reset-migrations 包,因此迁移文件夹不会变得复杂,所有内容都存储在单个 0001_initial.py 迁移中文件。

解决问题的方法很简单:停止这样做。

以这种方式重置迁移文件是一种高级且具有潜在危险的技术。它从来都不是必需的,但在某些情况下可能会有所帮助。迁移文件夹“变得复杂”并不是真正需要解决的问题,尤其是对于刚开始的项目。

危险之处在于,在设计上,它会抹去对模型和数据库所做更改的历史记录。因此,如果您在数据库未完全更新时运行它——正如您显然所做的那样——您已经删除了执行此操作所需的信息。 (具体来说,当您在迁移开发数据库之前重置迁移时,您删除了指定如何添加新列的文件。)

【讨论】:

这很有意义。我倾向于将此标记为正确,但让我今天测试一下不重置迁移和移动数据库连接,看看我是否遇到问题。我很清楚,你是说如果我不理会迁移文件(即不重置它们),我将能够切换数据库,运行 manage.py migrate 并且它将同步新数据库中的表是否存在正确? - 本质上意味着不使用 django-reset-migrations 是最好的选择。 @ViaTech:是的。事实上,这就是迁移的主要目的。请注意,此建议不会解决您现有的数据库问题。您表示愿意从头开始,所以这样做,以后就不会遇到这个问题了。 是的,我已经收集到这将解决我的问题,只要我保持迁移的完整性。太好了,谢谢!您能否描述一个重置迁移的“好情况”,以便我知道以供将来参考? @ViaTech:进行大量迁移的主要缺点是它会减慢测试速度,因为测试数据库每次都是从头开始构建的(除非您使用--keepdb)。这是一个常见的动机。请注意,Django 有一个内置的、更安全、不太全面的 migration squashing 版本。 太好了,我会在今天晚些时候有机会时研究 Django 的迁移压缩,谢谢!

以上是关于创建或更改 PostgreSQL 表以确保 Django 模型匹配的主要内容,如果未能解决你的问题,请参考以下文章

使用 Prisma 2 和 PostgreSQL 构建权限表以根据权限级别授权用户?

如何在 Sequelize 中创建一个表以使用 Node JS 存储在 Postgresql 中

问题设计审计表以跟踪更改

确保在启动共享表以共享图像之前渲染图像?

使用 PHP 和 Ajax 创建动态表以将数据插入表中,如果不在视图或第一页中,则无法使用按钮

如何在 Django ORM 中更改 PostgreSQL 的默认空排序行为