我正在处理一个执行日志记录到模型的单个TextField
属性的系统。
class A(models.Model):
log = models.TextField()
message = models.CharField()
def update(self, log=None, message=None)
if log is not None:
# Reading self.log is slow.
self.log = self.log + log
if message is not None:
self.message = message
self.save()
此日志可能变得非常大,因此连续日志记录(附加到日志)的操作会变得非常慢,因为Django必须不断从数据库中读取大日志字段并保存它。
a = A.objects.first()
a.update(log="More logging")
可以将 Update
更改为使用Django的纯数据库代理函数Concat
。
from django.db.models.function import Concat
from django.db.models import Value
def update(self, log=None, message=None)
if log is not None:
a.log = Concat('log', Value('More logging'))
if message is not None:
self.message = message
self.save()
a.log
保留为Concat
对象,a.log
的任何后续使用都将收到Concat
对象而不是原始字符串。这意味着任何后续更新都将导致更多的原始连接:
a = A.objects.first()
a.update(log='More logging') # a.log = "<Original>More Logging"
a.update(message="New Message") # a.log = "<Original>More LoggingMore Logging"
使用F
对象或Concat
之类的对象之后的计划是从数据库中重新读取它们。我宁愿不让调用者必须确保重新读取完成,而是在方法中完成。我想在self.refresh_from_db(fields=['log'])
之后update
内使用save
,但我担心的是,这样做会导致log
从数据库中读取,从而破坏了整个目的使用Concat
。执行一些时间测试表明,实际情况也是如此。
在a.log
被使用后,我该如何设置Concat
?