大型模型字段在管理站点中列出时导致MemoryError

时间:2019-12-26 17:37:55

标签: python django memory

我有以下模型:

class TemplateModel(models.Model):
    def __str__(self):
        return "{0} - Template - {1} - {2}".format(self.id, str(self.self.field2).upper(), str(self.self.field3))

    def __lt__(self, other):
        return self.id < other.id

    # primary key
    id = models.FloatField(primary_key=True, blank=True)

    # other small fields
    field2 = models.CharField('abbreviation', max_length=10, default=None, editable=False)
    field3 = models.CharField(max_length=100, default=None, editable=False)
    field4 = models.TextField(null=True, blank=True, default=None, editable=False)

    # very large field, up to 100MB large
    json_data = models.TextField(editable=False)

当我尝试在管理控制台中查看此模型时(我可以查看项目中所有各种模型的清单,然后可以单击并在其中进行编辑的对象列表),有时我(不一致)获取MemoryErrors或OperationalErrors。该请求也需要很长时间才能完成。这使我认为后端每次都会完全加载json_data字段,这会占用大量内存,在这种情况下完全没有必要。

当我在数据库中有大约18或19个实例时,这种情况就开始发生,此后变得越来越频繁。我通过向服务器添加更多的RAM(服务器是低RAM,只是一个普通的2GB虚拟机)来缓解该问题,但是这种方法不能扩展。

我尝试的另一种解决方案是遵循this answer的建议并将以下方法添加到模型中:

def get_queryset(self, request):
    qs = super(TemplateModel, self).get_queryset(request)
    # tell Django to not retrieve json_data field from DB
    qs = qs.defer('json_data')
    return qs

但这不能解决问题。理想情况下,我只是停止将json_data从数据库中拉出,因为直到以后我才需要它,并且那时没有问题,因为我只在一个数据库中访问一个TemplateModel实例。时间。我该怎么办?


这是整个追溯:

MemoryError traceback:

File "/opt/my_site/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)
File "/opt/my_site/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)
File "/opt/my_site/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in wrapper
  607.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/contrib/admin/sites.py" in inner
  223.             return view(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in changelist_view
  1803.             'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/query.py" in __len__
  250.         self._fetch_all()
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/query.py" in _fetch_all
  1183.             self._result_cache = list(self._iterable_class(self))
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/query.py" in __iter__
  54.         results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1093.                 return list(result)
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in cursor_iter
  1462.         for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in <lambda>
  1462.         for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/utils.py" in inner
  96.                 return func(*args, **kwargs)
Exception Type: MemoryError at /admin/my_site/templatemodel/


-----------------
OperationalError traceback:


File "/opt/my_site/local/lib/python3.6/site-packages/django/db/utils.py" in inner
  96.                 return func(*args, **kwargs)
The above exception (Could not decode to UTF-8 column 'json_data' with text '{"key": "OoX9J5r6wM6LRGdjKNxNrTOWwj2j1CgL1BssDgC/GhXhKBGLcfeKgRtvb4LX3uUazHaDDaB6syjhKSP+d0W3XDD4bX/U9G8sg24FAXJl0mwaKhDiA68MYJXPuNqunLf+gmH1v) was the direct cause of the following exception:
File "/opt/my_site/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)
File "/opt/my_site/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)
File "/opt/my_site/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in wrapper
  607.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/contrib/admin/sites.py" in inner
  223.             return view(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in changelist_view
  1803.             'selection_note': _('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/query.py" in __len__
  250.         self._fetch_all()
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/query.py" in _fetch_all
  1183.             self._result_cache = list(self._iterable_class(self))
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/query.py" in __iter__
  54.         results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size)
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1093.                 return list(result)
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in cursor_iter
  1462.         for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in <lambda>
  1462.         for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel):
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/utils.py" in inner
  96.                 return func(*args, **kwargs)
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/utils.py" in __exit__
  89.                 raise dj_exc_value.with_traceback(traceback) from exc_value
File "/opt/my_site/local/lib/python3.6/site-packages/django/db/utils.py" in inner
  96.                 return func(*args, **kwargs)
Exception Type: OperationalError at /admin/my_site/templatemodel/
Exception Value: Could not decode to UTF-8 column 'json_data' with text '{"key": "OoX9J5r6wM6LRGdjKNxNrTOWwj2j1CgL1BssDgC/GhXhKBGLcfeKgRtvb4LX3uUazHaDDaB6syjhKSP+d0W3XDD4bX/U9G8sg24FAXJl0mwaKhDiA68MYJXPuNqunLf+gmH1v

JSON的这一短段位于巨大的JSON区域的开头,尽管这甚至不是此键的全部值,更不用说第二个键了。

1 个答案:

答案 0 :(得分:1)

创建自定义ModelAdmin来定义所需的字段,而忽略json_data字段,是否有帮助?

class TemplateModelAdmin(admin.ModelAdmin):

    exclude = ('json_data',)

admin.site.register(TemplateModel, TemplateModelAdmin)

另外,将get_queryset()方法放在此类中,而不要放在模型本身中,就像在提供的链接中一样。