Django: 1.11
Я использую django-pyodbc-azure
в качестве моего бэкэнда Django.Он подключается к SQL Server 2012. У SQL Server есть ограничение в 2100 параметров.Когда я пытаюсь использовать prefetch_related
в наборе запросов, который выдаст более 2100 результатов ...
def object_search_list(request):
objects = MyModel.objects.filter(some_field='filter value').select_related('another_field').prefetch_related('a_third_field')
print(objects)
return render(request, 'objects/object_list.html', {'objects':objects})
... возвращается эта ошибка:
Exception Value: ('07002', '[07002] [Microsoft][SQL Server Native Client 11.0]COUNT field incorrect or syntax error (0) (SQLExecDirectW)')
Указывает набэкэнд pyodbc, используемый django-pyodbc-azure
.При просмотре функций (https://github.com/michiya/django-pyodbc-azure/blob/azure-2.1/sql_server/pyodbc/features.py), нет установленного max_query_params
. Я попытался вручную добавить max_query_params = 2100
. Это привело к той же ошибке. Установка этого значения на 2000 и 1000 также привела к той же ошибке.
Как настроить django-pyodbc-azure
для автоматической обработки этого ограничения SQL Server?
Бэкэнд Oracle для Django имеет такую функцию: https://github.com/django/django/blob/master/django/db/backends/oracle/features.py
ОБНОВЛЕНИЕ:
Я понял, что имя max_query_params
было новым для Django 2.0, поэтому я попытался max_limit_in_size
для соответствия Django 1.11. Просто django-pyodbc-azure
не поддерживает управляющий параметрсчитает и base.py
отменяет значение по умолчанию в Django base.py
?
ОБНОВЛЕНИЕ 2:
Я обновил до Django 2.1 и обновил django-pyodbc-azure
, чтобы соответствовать. Затем я отредактировалfeatures.py
для добавления max_query_params = 2000
в качестве функции. Другое место, где max_query_params
появляется в собственных бэкэндах Django, в этой функции - operations.py
(пример Oracle):
def bulk_batch_size(self, fields, objs):
"""Oracle restricts the number of parameters in a query."""
if fields:
return self.connection.features.max_query_params // len(fields)
return len(objs)
django-pyodbc-azure
имеет этофункции, и это выглядит так:
def bulk_batch_size(self, fields, objs):
"""
Returns the maximum allowed batch size for the backend. The fields
are the fields going to be inserted in the batch, the objs contains
all the objects to be inserted.
"""
objs_len, fields_len, max_row_values = len(objs), len(fields), 1000
if (objs_len * fields_len) <= max_row_values:
size = objs_len
else:
size = max_row_values // fields_len
return size
Кажется, лТо есть он уже позаботится о пакетировании с max_row_values
, установленным на 1000. Однако, та же ошибка сохраняется.Я также попытался изменить 1000 на max_query_params
безрезультатно.
Вот полный ответ:
Traceback:
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\backends\utils.py" in _execute
85. return self.cursor.execute(sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\sql_server\pyodbc\base.py" in execute
546. return self.cursor.execute(sql, params)
The above exception (('07002', '[07002] [Microsoft][SQL Server Native Client 11.0]COUNT field incorrect or syntax error (0) (SQLExecDirectW)')) was the direct cause of the following exception:
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\core\handlers\base.py" in _get_response
126. response = self.process_exception_by_middleware(e, request)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\core\handlers\base.py" in _get_response
124. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\contrib\auth\decorators.py" in _wrapped_view
21. return view_func(request, *args, **kwargs)
File "C:\Users\user\djangoproject\app\views.py" in object_list
486. return render(request, 'objects/object_list.html', {'objects':objects})
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\shortcuts.py" in render
36. content = loader.render_to_string(template_name, context, request, using=using)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\loader.py" in render_to_string
62. return template.render(context, request)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\backends\django.py" in render
61. return self.template.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\template_timings_panel\panels\TemplateTimings.py" in timing_hook
139. result = func(self, *args, **kwargs)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render
171. return self._render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\test\utils.py" in instrumented_test_render
96. return self.nodelist.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\loader_tags.py" in render
150. return compiled_parent._render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\test\utils.py" in instrumented_test_render
96. return self.nodelist.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\template_timings_panel\panels\TemplateTimings.py" in timing_hook
139. result = func(self, *args, **kwargs)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\loader_tags.py" in render
62. result = block.nodelist.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\loader_tags.py" in render
188. return template.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\template_timings_panel\panels\TemplateTimings.py" in timing_hook
139. result = func(self, *args, **kwargs)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render
173. return self._render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\test\utils.py" in instrumented_test_render
96. return self.nodelist.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render
937. bit = node.render_annotated(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\base.py" in render_annotated
904. return self.render(context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\template\defaulttags.py" in render
166. len_values = len(values)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in __len__
250. self._fetch_all()
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in _fetch_all
1188. self._prefetch_related_objects()
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in _prefetch_related_objects
723. prefetch_related_objects(self._result_cache, *self._prefetch_related_lookups)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in prefetch_related_objects
1569. obj_list, additional_lookups = prefetch_one_level(obj_list, prefetcher, lookup, level)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in prefetch_one_level
1699. all_related_objects = list(rel_qs)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in __iter__
268. self._fetch_all()
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\query.py" in _fetch_all
1186. self._result_cache = list(self._iterable_class(self))
File "C:\Users\user\installed\anaconda\envs\django2\lib\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 "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
1065. cursor.execute(sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\debug_toolbar\panels\sql\tracking.py" in execute
186. return self._record(self.cursor.execute, sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\debug_toolbar\panels\sql\tracking.py" in _record
124. return method(sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\backends\utils.py" in execute
100. return super().execute(sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\backends\utils.py" in execute
68. return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\backends\utils.py" in _execute_with_wrappers
77. return executor(sql, params, many, context)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\backends\utils.py" in _execute
85. return self.cursor.execute(sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\utils.py" in __exit__
89. raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\django\db\backends\utils.py" in _execute
85. return self.cursor.execute(sql, params)
File "C:\Users\user\installed\anaconda\envs\django2\lib\site-packages\sql_server\pyodbc\base.py" in execute
546. return self.cursor.execute(sql, params)
Exception Type: Error at url
Exception Value: ('07002', '[07002] [Microsoft][SQL Server Native Client 11.0]COUNT field incorrect or syntax error (0) (SQLExecDirectW)')