Ошибка Prefetch_related для SQL Server - PullRequest
0 голосов
/ 02 января 2019

Используя Django 2.X и драйвер Pyodbc (установленный из anaconda conda-forge django-pyodbc-azure) для MS Sql Server (не знаю, какая версия), я регулярно получаю ошибки, используя prefetch_related.Пример выглядит просто так:

for obj in MyORMType.objects.prefetch_related('otherormtype_set').all():
    pass

, где OtherOrmType имеет простой внешний ключ для MyOrmType, ошибка:

...
/opt/conda/lib/python3.6/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)
     83                 return self.cursor.execute(sql)
     84             else:
---> 85                 return self.cursor.execute(sql, params)
     86 
     87     def _executemany(self, sql, param_list, *ignored_wrapper_args):

/opt/conda/lib/python3.6/site-packages/sql_server/pyodbc/base.py in execute(self, sql, params)
    544         self.last_params = params
    545         try:
--> 546             return self.cursor.execute(sql, params)
    547         except Database.Error as e:
    548             self.connection._on_error(e)

ProgrammingError: ('The SQL contains -2098 parameter markers, but 128974 parameters were supplied', 'HY000')

Я могу вернуться к тупому эквиваленту:

for obj in MyORMType.objects.all():
    other_objs = obj.otherormtype_set.all()

но это, очевидно, довольно медленно.Эта ошибка регулярно возникает для меня при различных обстоятельствах в данной конкретной установке (всегда одна и та же версия Django, драйвер и БД), это не разовое раздражение.Это моя ошибка или проблема с SQL Server или Pyodbc (или Django)?Есть ли способ обойти ошибку без необходимости извлекать каждый obj.otherormtype_set по одному?

1 Ответ

0 голосов
/ 11 января 2019

Под капотом функция prefetch_related использует IN (...large number of IDs) запросы для извлечения объектов, что, по-видимому, является известной проблемой с пакетом django-pyodbc-azure, который вы используете.

Вы можете найти немного больше информации оGithub выдает сам пакет.

  1. https://github.com/michiya/django-pyodbc-azure/issues/101
  2. https://github.com/michiya/django-pyodbc-azure/issues/143

При быстром исследовании выясняется, что .features.max_query_params потребуетсянеобходимо отрегулировать что я и предложил сделать .

Похоже, что это может быть ограничение, аналогичное SQLite в отношении количества разрешенных параметров .

...