django-models - 将大量模型从 Foreigner Table 更新为 Django Rest 中的 Current Table
问题描述
我在 Django 模型中有 3 个模型和一个抽象模型。
我想在 ScentData 中添加字段并将域从子域复制到 Scentdata。
# Abstract Model
class TimeStampedModel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created_at = models.DateTimeField(
verbose_name='Create At',
auto_now_add=True
)
is_deleted = models.BooleanField(default=False)
modified = models.DateTimeField(auto_now=True)
deleted = models.DateTimeField(null=True, blank=True)
objects = NoDeleteManager()
objects_with_deleted = models.Manager()
class Meta:
abstract = True
ordering = ['created_at']
class Domain(TimeStampedModel):
name = models.CharField(
max_length=64,
null=False,
blank=False,
unique=False,
default=''
)
class SubDomain(TimeStampedModel):
name = models.CharField(
max_length=64,
null=False,
blank=False,
unique=False,
default=''
)
domain = models.ForeignKey(
'Domain',
on_delete=models.PROTECT,
related_name='subdomains'
)
class ScentData(TimeStampedModel):
name = models.CharField(
max_length=64,
blank=False,
null=False,
default=''
)
subdomain = models.ForeignKey(
'SubDomain',
on_delete=models.PROTECT,
related_name='scentdata_subdomain'
)
但现在我向ScentData模型添加了一个domain
字段。
class ScentData(TimeStampedModel):
name = models.CharField(
max_length=64,
blank=False,
null=False,
default=''
)
subdomain = models.ForeignKey(
'SubDomain',
on_delete=models.PROTECT,
related_name='scentdata_subdomain'
)
domain = models.ForeignKey(
'Domain',
on_delete=models.PROTECT,
related_name='scentdata_domain',
null=True,
blank=True
)
def set_domain(self):
self.domain = self.subdomain.domain
self.save()
return self
我已经编写了ModelViewSetset_domain
来在 ScentData 中运行函数,但我在Scentdata中有 200K 行,所以我的服务器无法处理这么长时间的更改。下面是我的 ViewSet。
class ScentDataViewSet(viewsets.ModelViewSet):
queryset = ScentData.objects.all()
@action(detail=False, methods=['GET'], url_path="reset_domain")
def reset_domain(self, pk=None, **kwargs):
scent_data = ScentData.objects.all()
for scent_data_obj in scent_data:
scent_data_obj.set_domain()
return Response({"detail": "success"})
是否有任何技术可以更快地将域移动到ScentData?
解决方案
您可以使用select_related
和改进此过程bulk_update
:
updated_scent_data = []
scent_data = ScentData.objects.select_related('subdomain__domain').all()
for scent_data_obj in scent_data:
scent_data_obj.domain = scent_data_obj.subdomain.domain
updated_scent_data.append(scent_data_obj)
ScentData.objects.bulk_update(updated_scent_data, ['domain'])
select_related
所以每次迭代scent_data
都不必scent_data_obj
为了得到subdomain.domain
.
bulk_update
更新ScentData
一个数据库命中中的所有对象。
推荐阅读
- mysql - SEL * 与 SEL 列
- android - 在主项目中显示注释
- directions - 在 Kakao 地图上显示路线,以 url 编码的开始/目的地
- python - 相当于 tensorflow 2.0 beta1 中的 tf.assign?
- flutter - 问题在列中展开的列表视图上方呈现小部件
- python - Pip 要为一个包删除的文件列表在哪里
- php - 从php调用动态axsoap服务方法时出错
- python - 在 Python 中将图像保存为 OIB 文件
- javascript - Chrome 扩展在打开新标签后退出运行 javascript
- mysql - 更新 MySQL 表中的行