为了账号安全,请及时绑定邮箱和手机立即绑定

Django:在相关模型上的 RunPython 迁移真的很慢

Django:在相关模型上的 RunPython 迁移真的很慢

波斯汪 2022-07-19 20:35:12
我正在尝试优化大型表(250K 对象)上的迁移速度。目标是根据与该行相关的对象的用户向每一行添加一个用户字段:我尝试使用 F 表达式,但遗憾的是 django 不允许它们中的关系。请注意,我主要是 SQL 的初学者 :)## models.pyclass Band(models.Model):    user = models.ForeignKey(        settings.AUTH_USER_MODEL,        on_delete=models.CASCADE,        null=True,        default=None)    ...class Album(models.Model):    band = models.ForeignKey(        Band        on_delete=models.CASCADE,        null=True,        default=None)    user = models.ForeignKey(        settings.AUTH_USER_MODEL,        on_delete=models.CASCADE,        null=True,        default=None)    ...## 0035_album_add_user.pydef forwards_add_user(apps, schema_editor):    Album = apps.get_model('band', 'Album')    db_alias = schema_editor.connection.alias    albums = Album.objects \        .using(db_alias) \        .filter(band__isnull=False) \        .select_related('band', 'band__user')    for each in albums:        each.user = each.band.user    Album.objects \        .using(db_alias) \        .bulk_update(albums, ['user'])class Migration(migrations.Migration):    dependencies = [ ... ]    operations = [        migrations.RunPython(forwards_add_user, reverse_add_user),    ]这个迁移目前在我的本地需要一个小时,并且在整个持续时间内数据库的使用率为 100%。感谢我的生产数据库,我有一个更好的 CPU,所以这让我很担心,关闭生产数据库一个小时并不是一个真正的选择。我正在研究两种不同的解决方案,这两种解决方案我都不知道如何完成: - 优化更多 python 代码以使其运行得更快 - 在迁移期间限制数据库的 CPU 消耗,使其保持可用。两者都是最好的情况:)我在生产中的 RDS 和本地的 Docker 上运行 Python3.6.9 和 Django2.2.9 和 PostgreSQL10.6。谢谢 !
查看完整描述

1 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

使用子查询更新字段,类似于以下内容,因为您不能在更新连接表中使用 F() 函数


Album.objects.update(

    user=Subquery(

        Band.objects.filter(

            id=OuterRef('band')

        ).values('user')[:1]

    )

)


查看完整回答
反对 回复 2022-07-19
  • 1 回答
  • 0 关注
  • 85 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信