网站首页 服务项目 客户案例 我们优势 主机域名 关于黑羽 联系黑羽

资讯中心
了解网站建设资讯引领网站建设开发方向
Sentry 开发者贡献指南-数据库迁移


Django 迁移是我们处理 Sentry 中数据库更改的方式。
Django 迁移官方文档:https://docs.djangoproject.com/en/2.2/topics/migrations/。
这些将涵盖了解迁移正在执行的操作所需的大部分内容。
请注意,对于所有这些命令,如果在 getsentry 存储库中,您可以将 getsentry 替换为 sentry。
sentry upgrade 会自动更新你的迁移。您也可以运行 sentry django migrate 来直接访问迁移命令。
将您的数据库移动到特定的迁移
当您要测试迁移时,这会很有帮助。
sentry django migrate - 请注意,migration_name 可以是部分匹配,通常数字就是你所需要的。
例如:sentry django migrate sentry 0005
这也可用于回滚迁移。如果你犯了错误,在开发中很有用。
为迁移生成 SQL
这对审查您的代码的人很有帮助,因为并不总是清楚 Django 迁移实际要做什么。
sentry django sqlmigrate
例如 sentry django sqlmigrate sentry 0003
这会根据您对模型所做的更改自动为您生成迁移。
sentry django makemigrations
或者
sentry django makemigrations 用于一个指定的 app。
例如 sentry django makemigrations sentry
当您在 pr 中包含迁移时,还要为迁移生成 sql 并将其作为注释包含在内,以便您的审阅者可以更轻松地了解 Django 正在做什么。
您还可以使用 sentry django makemigrations --empty 生成空迁移。这对于数据迁移和其他自定义工作很有用。
合并到 master 时,您可能会注意到与 migrations_lockfile.txt 的冲突。这个文件是为了帮助我们避免将具有相同迁移编号的两个迁移合并到 master,如果您与它发生冲突,那么很可能有人在您之前提交了迁移。
在运行迁移时,我们需要注意一些事项。
如果(数据)迁移涉及大表或未索引的列,最好迭代整个表而不是使用 filter。例如:
因为 EnvironmentProject 行太多,这会一次将太多行带入内存。相反,我们应该使用 RangeQuerySetWrapperWithProgressBar 遍历所有 EnvironmentProject 行,因为它会分块进行。例如:
我们通常更喜欢避免将 .filter 与 RangeQuerySetWrapperWithProgressBar 一起使用。由于它已经通过 id 对表进行排序,因此我们无法利用字段上的任何索引,并且可能会为每个块扫描大量行。这会运行得更慢,但我们通常更喜欢这样,因为它在更长的时间内平均负载,并使每个查询获取每个块的成本相当低。
我们更喜欢使用 CREATE INDEX CONCURRENTLY 在现有的大型表上创建索引。当我们这样做时,我们无法在事务中运行迁移,因此使用 atomic = False 来运行这些很重要。
由于我们的部署过程,这很复杂。当我们部署时,我们运行迁移,然后推出应用程序代码,这需要一段时间。这意味着如果我们只是删除一个列或模型,那么 sentry 中的代码将查找这些列/表并在部署完成之前出错。在某些情况下,这可能意味着 Sentry 在部署完成之前很难停机。
为避免这种情况,请执行以下步骤:
这是删除已经可以为空的列的示例。首先我们从模型中删除列,然后修改迁移以仅更新状态而不进行数据库操作。
一旦部署完成,我们就可以部署实际的列删除。这个 pr 只会有一个迁移,因为 Django 不再知道这些字段。请注意,反向 SQL 仅适用于开发人员,因此可以不分配默认值或进行任何类型的回填:
如果该表在其他表中被引用为外键,则需要格外小心。在这种情况下,首先删除其他表中的外键列,然后返回到此步骤。
这是删除此模型的示例:
首先,我们检查了它没有被任何其他模型引用,它没有。接下来,我们需要删除和 db 级外键约束。为此,我们改变这两列并生成一个迁移:
迁移中的操作看起来像
我们可以看到它生成的 sql 只是删除了 FK 约束
所以现在我们部署它并进入下一阶段。
下一阶段涉及从代码库中删除对模型的所有引用。所以我们这样做,然后我们生成一个迁移,从迁移状态中删除模型,而不是数据库。此迁移中的操作如下所示
并且生成的 SQL 显示没有发生数据库更改。所以现在我们部署它并进入最后一步。
在这最后一步中,我们只想手动编写 DDL 来删除表。所以我们使用 sentry django makemigrations --empty 来产生一个空的迁移,然后修改操作如下:
然后我们部署它,我们就完成了。
创建外键大多没问题,但是对于像 Project、Group 这样的大/繁忙的表,由于获取锁的困难,它可能会导致问题。您仍然可以创建 Django 级别的外键,而无需创建数据库约束。为此,请在定义键时设置 db_constraint=False。
重命名表很危险,会导致停机。发生这种情况的原因是在部署期间将运行旧/新代码的混合。因此,一旦我们在 Postgres 中重命名该表,如果旧代码尝试访问它,它就会立即开始出错。有两种方法可以处理重命名表:
创建新列时,它们应始终创建为可为空的。这是出于两个原因:
将 not null 添加到列可能很危险,即使该列的表的每一行都有数据。这是因为 Postgres 仍然需要对所有行执行非空检查,然后才能添加约束。在小表上这可能没问题,因为检查会很快,但在大表上这可能会导致停机。这里有几个选项可以确保安全:
向现有表添加具有默认值的列是危险的。这需要 Postgres 锁定表并重写它。相反,更好的选择是:
在 Postgres 中添加没有默认值的列,但在 Django 中添加默认值。这使我们能够确保所有新行都具有默认值。这是通过修改迁移文件以包含 migrations.SeperateDatabaseAndState 来完成的
改变列的类型通常是危险的,因为它需要重写整个表。有一些例外:
对于任何其他类型,最好的前进路径通常是:
重命名列是危险的,会导致停机。发生这种情况的原因是在部署期间将运行旧/新代码的混合。因此,一旦我们在 Postgres 中重命名该列,如果旧代码尝试访问它,它就会立即开始出错。有两种方法可以处理重命名列:
一般来说,这是不值得做的,与回报相比,这需要冒很多风险/付出很多努力。
鸿蒙官方战略合作共建——HarmonyOS技术社区

网页制作的服务
网站开发服务
自贡黑羽网络品牌建站
自贡本地做网站就选黑羽网络
Tel:0813-5104030 15348110304 QQ或微信:22232591
地址:四川省自贡市自流井区丹佳大街泰丰大厦写字楼19楼10号
Copyright © 2018-2058 自贡黑羽网络科技有限公司 All rights reserved. ICP备案号 : ICP备12014994号-1 技术支持:黑羽网络
自贡网站建设,网页设计制作与开发,自贡网络公司推荐品牌,关键词: 自贡网站制作 自贡做网站 自贡网络公司 自贡网页制作 自贡做网站 网站地图xml 网站地图html 网站地图txt