Django:相关模型上的RunPython迁移确实很慢

问题描述 投票:2回答:1

我正在尝试优化大型表(250K对象)上的迁移速度。目标是根据与该行相关的对象的用户,向每行添加一个用户字段:

我尝试使用F表达式,但可惜django不允许它们之间存在关系。请注意,我主要是SQL的初学者:)

## models.py
class 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.py
def 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上运行带有Django2.2.9和PostgreSQL10.6的Python3.6.9,并且在本地Docker中运行。

谢谢!

python sql django postgresql django-migrations
1个回答
0
投票

不确定语法,请尝试以下方法:

Album.objects.all().update(user=F('band__user_id'), )

在此之前尝试运行迁移:

Album
...
    band = models.ForeignKey(
      ...
      db_index=True,
    )

https://docs.djangoproject.com/en/3.0/topics/db/queries/#updating-multiple-objects-at-once

© www.soinside.com 2019 - 2024. All rights reserved.