Mysql 参数化Django原始查询产生的结果与非参数化原始查询不同
我正在使用带有两个参数的SQL字符串对Django模型进行原始查询。令人头痛的是,如果我使用字符串替换来填充参数,我会得到比使用参数替换更多的结果。在后一种情况下,结果是正确的,只是不完整。代码如下所示,唯一的变化是我省略了确切的SQL:Mysql 参数化Django原始查询产生的结果与非参数化原始查询不同,mysql,django,django-models,Mysql,Django,Django Models,我正在使用带有两个参数的SQL字符串对Django模型进行原始查询。令人头痛的是,如果我使用字符串替换来填充参数,我会得到比使用参数替换更多的结果。在后一种情况下,结果是正确的,只是不完整。代码如下所示,唯一的变化是我省略了确切的SQL: # I have a long and ornate SQL statement that looks basically like this. sql = "SELECT blah blah WHERE something = %s AND somethin
# I have a long and ornate SQL statement that looks basically like this.
sql = "SELECT blah blah WHERE something = %s AND something_else in (%s)"
# If I do a raw query with string substitution I get more results (22) ...
sqlInsecureFilled = sql % (divID, storeRestrictStr)
promos_insecured = Promotions.objects.raw(sqlInsecureFilled)
# ... than if I use a parameterized raw query, which produces (10)
promos_secure = Promotions.objects.raw(sql, [divID, storeRestrictStr])
但它变得更奇怪了。如果我从命令行执行此操作,从原始查询对象(即promos\u secure.query)获取SQL并将其复制到Sequel Pro终端,那么两个查询都会产生相同数量的结果——22!然而:
In [35]: [len(list(promos_insecured)), len(list(promos_secure))]
Out[35]: [22, 10]
总而言之,查询看起来是一样的(相当长,所以很难准确地说出来),当promos_xx.query字符串被复制到MySQL终端时,它们会生成完整的结果集。然而,当如上所示执行时,参数化版本返回10个结果,而另一个版本返回完整的22个结果
为了完整起见,这里是promos_secure.query(promos_unsecured是相同的):
字符串替换的问题是,引用很可能做了一些你意想不到的事情。有些事情可以尝试:
- 现在,您正在以字符串形式传递ID列表(
)。尝试将其作为列表传递storeRestrictStr
- 安装并使用它查看正在生成的实际SQL及其输出
- 你没有说10个结果是否正确,22个结果是否有12个错误匹配,或者22个结果是否正确,10个结果是否缺少12个,或者介于两者之间
SELECT DISTINCT promotion_id, promotion_name, promotion_up_date, promotion_down_date, promotion_asset_id, promotion_notes, promotion_promo_id FROM promotions, promo_detail WHERE promotion_id = promo_detail_promotion_id AND promotion_start_date < now() AND promotion_end_date > now() AND promo_detail_cust_division_id = 1 AND promo_detail_not_expired = 1 AND promo_detail_store_id in (8214, 8217, 4952, 8194, 8198, 8162, 5010, 5011, 5012, 8219, 8182, 5048, 5076, 5095, 5096, 5102, 5109, 5131, 5156, 5160, 5161, 5165, 5166, 5173, 5182, 5198, 5200, 5201, 5202, 5203, 5227, 5228, 5229, 5230, 5232, 5233, 5234, <bunch of other comma-separated numbers omitted>, 9281) ORDER BY promotion_end_date ASC
promo_u = promotions.models.Promotions.objects.raw(sql % (1, storeRestrictStr))
promo_s = promotions.models.Promotions.objects.raw(sql, (1, storeRestrictStr))
pid_u = [s.promotion_id for s in promo_u]
pid_s = [s.promotion_id for s in promo_s]
In [76]: [len(list(pid_u)), len(list(pid_s))]
Out[76]: [22, 10]
# You can see the smaller number of results is a subset of the larger.
In [77]: [pid in pid_u for pid in pid_s]
Out[77]: [True, True, True, True, True, True, True, True, True, True]
# The larger number results shows no obvious pattern as to why they're missing.
In [87]: [pid in pid_s for pid in pid_u]
Out[87]: [False, False, False, False, True, False, False, False, True, True, True, True,
True, False, True, False, False, True, False, True, False, True]