代码之家  ›  专栏  ›  技术社区  ›  scnerd

针对SQL Server的预取相关失败

  •  1
  • scnerd  · 技术社区  · 6 年前

    使用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版本、驱动程序和db),这个错误经常发生,这不是一次性的麻烦。这是我的错误还是SQL Server或PYODBC(或Django)的问题?有没有一种方法可以解决这个错误而不必获取每个错误 obj.otherormtype_set 一次一个?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Simon Charette    6 年前

    在引擎盖下面 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 需要调整的是 what I suggested doing .

    它看起来可能是一个类似于 SQLite one with regards to number of allowed parameters .