Django数据库访问优化

时间:2014-06-24 07:16:07

标签: django django-queryset

对于下面给出的这段代码,我几乎没有问题:

    architects_list=[8757,8755,7066,8736,6961,6955,4830,6949,208,4876,59,115]
    clauses = ' '.join(['WHEN id=%s THEN %s' % (pk, i) for i, pk in enumerate(architects_list)])
    ordering = 'CASE %s END' % clauses
    architects = User.objects.filter(pk__in=architects_list).extra(select={'ordering': ordering}, order_by=('ordering',))
    other_architects= User.objects.filter(Iam='Architect').exclude(pk__in=architects_list).annotate(pd =Count('projectdetail')).order_by('-pd')
    archs_all = architects|other_architects
  1. 当我使用“|”连接架构师和其他_architects时,我得到一个错误“字段列表中的列'id'是不明确的”错误archs_all = architects|other_architects。当我使用list(itertools.chain(architects,other_architects))时,一切都很顺利。我不想要第二种方法,因为我怀疑它会膨胀记忆。

  2. 将具有百万个对象的查询集传递给分页器是否内存效率低,如果是,那么替代方案是什么?

  3. 回溯:

    File "/home/harshai3/django/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
      114.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/views/generic/base.py" in view
      69.             return self.dispatch(request, *args, **kwargs)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/views/generic/base.py" in dispatch
      87.         return handler(request, *args, **kwargs)
    File "/home/harshai3/django/zingyhomes_lateral/apps/project/views.py" in get
      1251.         arch_objs = archs.page(1)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/core/paginator.py" in page
      50.         number = self.validate_number(number)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/core/paginator.py" in validate_number
      39.         if number > self.num_pages:
    File "/home/harshai3/django/lib/python2.7/site-packages/django/core/paginator.py" in _get_num_pages
      86.             if self.count == 0 and not self.allow_empty_first_page:
    File "/home/harshai3/django/lib/python2.7/site-packages/django/core/paginator.py" in _get_count
      72.                 self._count = self.object_list.count()
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/models/query.py" in count
      291.         return self.query.get_count(using=self.db)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/models/sql/query.py" in get_count
      390.         number = obj.get_aggregation(using=using)[None]
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/models/sql/query.py" in get_aggregation
      356.         result = query.get_compiler(using).execute_sql(SINGLE)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
      781.         cursor.execute(sql, params)
    File "/home/harshai3/django/lib/python2.7/site-packages/debug_toolbar/panels/sql/tracking.py" in execute
      174.         return self._record(self.cursor.execute, sql, params)
    File "/home/harshai3/django/lib/python2.7/site-packages/debug_toolbar/panels/sql/tracking.py" in _record
      104.             return method(sql, params)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/backends/util.py" in execute
      69.             return super(CursorDebugWrapper, self).execute(sql, params)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/backends/util.py" in execute
      53.                 return self.cursor.execute(sql, params)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/utils.py" in __exit__
      99.                 six.reraise(dj_exc_type, dj_exc_value, traceback)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/backends/util.py" in execute
      53.                 return self.cursor.execute(sql, params)
    File "/home/harshai3/django/lib/python2.7/site-packages/django/db/backends/mysql/base.py" in execute
      124.             return self.cursor.execute(query, args)
    File "/home/harshai3/django/lib/python2.7/site-packages/MySQLdb/cursors.py" in execute
      201.             self.errorhandler(self, exc, value)
    File "/home/harshai3/django/lib/python2.7/site-packages/MySQLdb/connections.py" in defaulterrorhandler
      36.     raise errorclass, errorvalue
    
    Exception Type: OperationalError at /find-architects/
    Exception Value: (1052, "Column 'id' in field list is ambiguous")
    

1 个答案:

答案 0 :(得分:1)

我认为id中的clauses会导致歧义,因为用户表和项目明细表都有id字段。

您可以通过明确定义表名来避免这种歧义:

clauses = ' '.join(['WHEN %s.id=%s THEN %s' % (User._meta.db_table, pk, i) for i, pk in enumerate(architects_list)])

但是,我不认为这会解决你所有的问题。带注释的查询集通常不能组合,我认为第二个查询集的注释总是丢失(虽然我不是100%确定它是如何工作的)。两个不同排序的查询集的组合排序不能按原样组合。

如果为SQL CASE指定默认值,则可以将查询合并为单个查询:

from django.db.models import Q

architects_list=[8757,8755,7066,8736,6961,6955,4830,6949,208,4876,59,115]
clauses = ' '.join(['WHEN id=%s THEN %s' % (pk, i) for i, pk in enumerate(architects_list)])
clauses += ' ELSE 0' # or 999, depending on if you want the `other_architects` first or last
ordering = 'CASE %s END' % clauses
architects = (User.objects.filter(Q(id__in=architects_list) | Q(Iam='Architect'))
              .extra(select={'ordering': ordering})
              .annotate(pd=Count('projectdetail'))
              .order_by('ordering', '-pd'))