Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Python在子句中设置SQL字符串格式_Python_Mysql_Sql_Django - Fatal编程技术网

如何使用Python在子句中设置SQL字符串格式

如何使用Python在子句中设置SQL字符串格式,python,mysql,sql,django,Python,Mysql,Sql,Django,我试图创建一个声明,如下所示: SELECT * FROM table WHERE provider IN ('provider1', 'provider2', ...) 但是,我在DjangoAPI中的字符串格式设置方面遇到了一些问题。以下是我目前掌握的情况: profile = request.user.get_profile() providers = profile.provider.values_list('provider', flat=True) # [u'provider1',

我试图创建一个声明,如下所示:

SELECT * FROM table WHERE provider IN ('provider1', 'provider2', ...)
但是,我在DjangoAPI中的字符串格式设置方面遇到了一些问题。以下是我目前掌握的情况:

profile = request.user.get_profile()
providers = profile.provider.values_list('provider', flat=True) # [u'provider1', u'provider2']
providers = tuple[str(item) for item in providers] # ('provider1', 'provider2')

SQL = "SELECT * FROM table WHERE provider IN %s"
args = (providers,)
cursor.execute(sql,args)

DatabaseError
(1241, 'Operand should contain 1 column(s)')

在将字符串传递给游标对象以执行之前,您可能应该进行字符串替换:

sql = "SELECT * FROM table WHERE provider IN (%s)" % \
        (','.join(str(x) for x in providers))
cursor.execute(sql)

MySQLdb有一种方法可以帮助实现这一点:

医生

字符串\u文本。。。 string_literalobj-将对象obj转换为SQL字符串文字。 这意味着,任何特殊的SQL字符都将被转义,并将其封闭 在单引号内。换句话说,它执行以下操作:

"'%s'" % escape_string(str(obj))

Use connection.string_literal(obj), if you use it at all.
_mysql.string_literal(obj) cannot handle character sets.
用法


因此,您需要ID的字符串输入:

some_vals = '1 3 5 76 5 4 2 5 7 8'.split() # convert to suitable type if required
SomeModel.objects.filter(provider__in=some_vals)

试试这个。。。。应该有用

SQL = "SELECT * FROM table WHERE provider IN %s"%(providers)
exec 'cursor.execute("%s")'%(SQL)

另一个我并不特别喜欢的答案,但它适用于您明显的用例:

providers = tuple[str(item) for item in providers] # ('provider1', 'provider2')
# rest of stuff...

SQL = 'SELECT * FROM table WHERE provider IN {}'.format(repr(providers))
cursor.execute(SQL)


好奇的既然已经有了django ORM,为什么还要在查询中使用原始sql?@jdi这是一个很长的sql查询,我正在基于一些用户输入的大约20行长的值构建字符串连接。ORM有聚合。但是我想我必须相信你的话,ORM不能做到这一点:-我在这里使用@jdi-你正在ORM中查询的表是吗?轻微编辑:我不支持jdi,我的意思是,在某种程度上,我的观点有些混乱…@JonClements:Jon,我被冒犯了。我们谈到在公共场合要诚实。David,我们在一起,我们对数据库ORMS也有相似的看法这有点有限,因为它假设列表的长度,对吧?这可能会有问题,因为字符串没有被引用。也许用repr替换str?也可以在连接中添加引号,例如%''+'',''。在providers+''中为x添加joinstrx-这可能会被视为有点黑客行为,但我认为这是此解决方案所必需的。FWIW,此方法容易受到SQL注入攻击。jdi接受的答案更安全。是的,我在主要评论中询问了这一点。OP说他们选择生食有一个特定的原因query@jdi有趣-如果对象在ORM中,那么可以从这个答案中检索SQL查询。否则,我只能认为他们在质疑ORM之外的东西。我完全同意你的看法,这是肯定的。我们只能假设OP有ORM无法满足的需求。这很酷。不知道string_literal方法。我假设,由于MySQLdb非常严格地遵循db-api,因此大多数实现中都存在这种情况??sqlite3、postgres等都可以追溯到docs@Justin.Wood:老实说,我也不太了解它,但我以前没有太多使用MySQLdb和传递元组值的经验。它总是一个怪物。我刚才也看了这张的文件:-整洁。我在一些不使用ORM的遗留代码库中工作,我们经常得到这种东西。所以这对我来说是一个很大的好处。你在文档里有这个链接吗?找不到它。尽管在源代码中很容易找到。@Justin.Wood:奇怪的是,在某些版本中,它只是简单地称为literal:Nah,这是MySQLdb的一个内部函数。你应该使用你在答案中使用的语法。它在源头卢克def_get_string_literalobj:def string_literalobj,dummy=None:return db.string_literalobj return string_literal def_get_unicode_literal:def unicode_literalu,dummy=None:return db.literalu.encodeunicode_literal.charset return unicode_literal`还可以写'…{!r}。formatproviders我猜-只是取决于taste这个选项不好,因为如果列表中只有1i项,那么末尾将有一个逗号,这是无效的语法
SQL = "SELECT * FROM table WHERE provider IN %s"%(providers)
exec 'cursor.execute("%s")'%(SQL)
providers = tuple[str(item) for item in providers] # ('provider1', 'provider2')
# rest of stuff...

SQL = 'SELECT * FROM table WHERE provider IN {}'.format(repr(providers))
cursor.execute(SQL)