我需要使用MySQLdb从Python脚本运行一系列SQL select语句。我想传递给select语句的变量之一叫做unit_ids
。我已经尝试将unit_ids
视为字符串以及字符串元组。最初,反斜杠被插入到字符串中。在网上浏览后,我已经能够避免使用反斜杠,但现在插入了额外的引号。这是我目前的代码:
connection = MySQLdb.connect('localhost', 'root', '*****', 'test')
cur = connection.cursor
unit_ids = ('0A1', '0A2', '0A3', '0A4')
attr = 'sample'
cur.execute("""SELECT COUNT(*) FROM test WHERE attribute = %s AND unit_id IN %r""", (a, tuple(unit_ids)))
使用cur._last_executed
,我可以看到执行的实际SQL语句是:
SELECT COUNT(*) FROM test WHERE attribute = 'sample' AND unit_id IN ("'0A1'", "'0A2'", "'0A3'", "'0A4'")
为了让('0A1', '0A2', '0A3', '0A4')
在SQL语句中保持不变,我需要改变什么?
更新:这是即使使用%s
时我得到的确切输出:
>>> cn = MySQLdb.connect('localhost', 'root', '***', '***')
>>> c = cn.cursor()
>>> unit_ids = ('0A1', '0A2', '0A3', '0A4')
>>> a = 'foo'
>>> c.execute("""select count(*) from model_test where attribute = %s and unit_id in %s""", (a, unit_ids))
1L
>>> print(c._last_executed)
select count(*) from model_test where attribute = 'foo' and unit_id in ("'0A1'", "'0A2'", "'0A3'", "'0A4'")
此时,我想我可能只需要为unit_ids
的每个元素创建单独的变量(例如unit_id1 = '0A1'
)。顺便说一句,我正在使用Python 2.7.9和MySQL Server 5.6。
更新2:@thebjorn解决了它:我的MySQLdb版本已经过时了。升级后,SQL语句中不再插入额外的引号。
答案 0 :(得分:1)
你不需要任何魔法,只需按常规的mysql方式进行:
connection = MySQLdb.connect('localhost', 'root', '*****', 'test')
cur = connection.cursor()
unit_ids = ('0A1', '0A2', '0A3', '0A4')
attr = 'sample'
cur.execute("""SELECT COUNT(*) FROM test WHERE attribute = %s AND unit_id IN %s""", (a, unit_ids))
我能看到的唯一皱纹是,如果a
未被包含且unit_ids
只有一个项目,那么元组语法可能会让你失望。如果您将unit_ids
放入列表中,那么语法就不会那么尴尬:
unit_ids = ('0A1',)
cur.execute("SELECT COUNT(*) FROM test WHERE unit_id IN %s", (unit_ids,))
当内联成为:
cur.execute("SELECT COUNT(*) FROM test WHERE unit_id IN %s", (('0A1',),))
VS。使用列表(一个参数,该参数是一个项目列表):
cur.execute("SELECT COUNT(*) FROM test WHERE unit_id IN %s", [['0A1']])
您可以对所有mysql参数使用%s
(也可以使用其他几个参数,但不能使用%r
- 这不是字符串插值)。
更新:你必须以不同的方式做某事 ..这是cursor._last_executed的输出
>>> cn = MySQLdb.connect('server', 'user', 'password', 'database')
>>> c = cn.cursor()
>>> unit_ids = ('0A1', '0A2', '0A3', '0A4')
>>> c.execute("select count(*) from foo where id in %s", (unit_ids,))
Traceback (most recent call last):
File ...
_mysql_exceptions.ProgrammingError: (1146, "Table 'djangodevelop.foo' doesn't exist")
>>> c._last_executed
"select count(*) from foo where id in ('0A1','0A2','0A3','0A4')"
>>>
答案 1 :(得分:0)
请勿在{{1}}中使用%r
。在构建SQL查询时,Python-Mysql数据库API仅支持unit_id IN %r
作为占位符。
在前面的示例中,我们将SELECT语句存储在变量查询中。请注意,我们使用的是未标注的%s-markers,其中应该包含日期。 Connector / Python将hire_start和hire_end从 Python类型转换为MySQL理解的数据类型并添加所需的引号。在这种情况下,它用'1999-01-01'替换第一个%s,用'1999-12-31'替换第二个%s。
您可以在Python-MySql docs中看到类似的警告和用法。
%s