Django从queryset中获取查询.返回无效参数



当我尝试从django queryset获取查询时,它返回没有引号的参数,这使得它是一个无效的查询

我有一个django代码如下:

qs = Sample.objects.filter(data_date__range=[start_date, end_date])

当我试图获得查询,以便我可以使用pyodbc查询它(我发现django的查询需要5秒,pyodbc需要<1为50k+行),我试图得到这样的查询:

str(qs.query)

但是,对于不带引号的参数,例如,返回的查询是

SELECT * FROM [sample] WHERE [data_date] 
BETWEEN 2019-01-01 00:00:00 AND 2022-01-01 00:00:00

显而易见,两个datetime变量缺少引号,因此当我尝试使用pd.read_sql_query(query, conn)运行查询时,我会得到指向这些参数的错误。这不仅仅是日期参数,如果我尝试使用其他任何东西过滤,我得到同样的问题。

查询不带引号时出错

Execution failed on sql 'SELECT * FROM [sample] WHERE [sample].[data_date] BETWEEN 2019-01-01 00:00:00 AND 2022-01-01 00:00:00': ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '00'. (102) (SQLExecDirectW)")

我想知道是否有任何其他方式从django queryset生成查询,以便我可以使用pyodbc或其他任何方式运行它以获得更快的结果。

我使用Django 3.2sql-server

更新:

数据库上的索引

...
[sample_data_date] (Non-unique, Non-clustered)
AK (Unique, Non-clustered)
PK (clustered)
...

经过一番挖掘,我找到了自己问题的答案。
在这里发布,这样别人就不用像我一样搜索那么多了。

证明queryset.query不返回有效的SQL。我们需要使用.sql_with_params()分别获取查询和参数。

最后的代码看起来像这样:

qs = Sample.objects.filter(data_date__range=[start_date, end_date])
query, params = qs.query.sql_with_params()
# pyodbc uses "?" vs django returns "%s" as placeholder
query = query.replace("%s", "?")
df = pd.read_sql(query, pyodbc_conn, params=params)

像这样使用pyodbc查询需要<1秒,而使用Django ORM查询56000行x 5列需要5秒。

这个Django票据帮了很大的忙。

相关内容

  • 没有找到相关文章