如何在 Django 中为“in”SQL 子句传递值列表

Posted

技术标签:

【中文标题】如何在 Django 中为“in”SQL 子句传递值列表【英文标题】:How to pass a list of values for an `in` SQL clause in Django 【发布时间】:2014-07-16 06:09:19 【问题描述】:

我需要在我正在编写的 Django 应用程序中使用原始 SQL 查询。 SQL 查询在where 语句中包含in 子句:

select *
from abc_mymodel
where some_fk in (1,2,3)
and some_status = 'foo'

我非常支持将 SQL 参数作为参数传递。对于单值的,这很容易完成。但是,我不确定如何(或是否)可以为 in 子句做到这一点。理想情况下,我想做这样的事情:

sql = """
    select *
    from abc_mymodel
    where some_fk in %s
    and some_status = %s
"""
my_list = [1,2,3]
my_status = 'foo'
trinkets = MyModel.objects.raw(
    sql,
    params=(my_list, my_status)
)

我知道我可以使用字符串组合来编写in 子句,并将参数用于剩余值。但是,我很好奇是否也可以将参数用于 in 子句。

【问题讨论】:

这个问题明确要求原始 sql 查询,所以我不认为它是重复的。 【参考方案1】:

根据Django docs on raw()

params 是参数的列表或字典。您将在查询字符串中使用 %s 占位符作为列表...这样的占位符将被 params 参数中的参数替换。

方便地,原始查询很容易在 django shell 中进行测试。如果您只是输入您的 raw() 查询,它将打印一个 RawQuerySet 与您的查询结果:

>>> from django.contrib.auth.models import User
>>> pk_list = (1, 3, 6)
>>> User.objects.raw('SELECT * FROM auth_user WHERE id IN %s', params=[pk_list])
<RawQuerySet: 'SELECT * FROM auth_user WHERE id IN (1, 3, 6)'>

如您所见,params 中的任何内容都会放入原始查询中。在您的示例中,您需要将 my_list 更改为元组(否则它将看起来像“IN [1,2,3]”)并将您的 params 输入更改为列表( params=[my_list, my_status])。

【讨论】:

总是忘记把列表转成元组,谢谢! 注意,这不适用于只有一项的元组。字符串输出是 Python 格式 (34,),SQL 会阻塞。【参考方案2】:

尝试这种方式进行 django orm 类型查询:

list = [1,2,3]
choices = Model.objects.filter(columnName__in=list)

在你的情况下:

list = [1,2,3]
choices = abc_mymodel.objects.filter(some_fk__in=list)

【讨论】:

这不是我要问的。我需要一种方法来处理原始 SQL 查询。 我是来找这个的。

以上是关于如何在 Django 中为“in”SQL 子句传递值列表的主要内容,如果未能解决你的问题,请参考以下文章

将列表传递给 HQL 或 SQL 中的 IN 子句?

我可以使用Java代码在sql语句(Oracle)的IN子句中传递字符串列表吗

在 Sql Server 中将集合作为参数传递时使用 IN 子句

将值列表从 Python 传递到 SQL 查询的 IN 子句

Netezza 中可以传递 IN 子句的最大参数

HANA - 将字符串变量传递到 SQL 脚本中的 WHERE IN() 子句