连接到大型TextField

时间:2018-01-05 10:07:56

标签: python-2.7 django-1.8

我正在处理一个执行日志记录到模型的单个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

0 个答案:

没有答案