2014-06-24 52 views
0

我有幾個問題在我腦海中運行下面給出這個給定的一段代碼:Django的數據庫訪問優化

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. 當我串聯建築師和other_architects使用「|」,我得到一個錯誤「字段列表中的列'id'不明確」錯誤archs_all = architects|other_architects。當我使用list(itertools.chain(architects,other_architects))一切順利。我不想第二種方法,因爲我懷疑它膨脹了記憶。

  2. 是否將具有百萬對象的查詢集傳遞給分頁程序是內存效率低下的,如果是的話還有什麼選擇?

回溯:

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") 
+3

@Sahilkalra你錯了兩個查詢將組合查詢集時進行 - 這是一個常見的誤解。該查詢將被合併到一個單獨的語句中,但查詢的執行將被延遲直到查詢集被評估。此外,'chain()'將評估查詢集,而不是使用'qs.iterator()'函數,因此完整的查詢集結果將被緩存在內存中。 – knbk

+0

納什,你可以發佈完整的追溯?最好也是'str(archs_all.query)'的結果。至於2),不,這不是內存低效的,因爲它將使用「LIMIT 10」(和可選的「OFFSET N」)SQL語句,因此僅從數據庫接收10個結果。 – knbk

+0

@knbk這裏是跟蹤http://pastebin.com/5N24k8Ky – nash

回答

1

我想在你的clausesid引起歧義,同時作爲用戶表和項目詳細信息表有一個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')) 
+0

感謝您的幫助..那麼做 – nash