Django:相关模型上的 RunPython 迁移真的很慢
Django: Really slow RunPython migration on related models
我正在尝试优化大型 table(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 完成,使其保持可用。
两者都是最好的情况:)
我正在 运行宁 Python3.6.9 与 Django2.2.9 和 PostgreSQL10.6 在生产中的 RDS 和本地 Docker 中。
谢谢!
使用子查询更新字段,类似于下面的内容,因为您不能在更新连接表中使用 F() 函数
Album.objects.update(
user=Subquery(
Band.objects.filter(
id=OuterRef('band')
).values('user')[:1]
)
)
我正在尝试优化大型 table(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 完成,使其保持可用。 两者都是最好的情况:)
我正在 运行宁 Python3.6.9 与 Django2.2.9 和 PostgreSQL10.6 在生产中的 RDS 和本地 Docker 中。
谢谢!
使用子查询更新字段,类似于下面的内容,因为您不能在更新连接表中使用 F() 函数
Album.objects.update(
user=Subquery(
Band.objects.filter(
id=OuterRef('band')
).values('user')[:1]
)
)