Python,MySQLdb和转义表名?

时间:2011-07-07 23:34:56

标签: python mysql-python

我可能遗漏了一些显而易见的东西,但我无法弄清楚我的代码与我在MySQLdb的在线文档中看到的各种示例有何不同。

我是编程python的新手,对perl更有经验。我想要做的是尽早养成一些好习惯(比如perl我总是从'use strict; use warnings'开始),所以我试图确保我在一个独立的文件中创建可重用的函数( funct.py)以节省我的时间。

我有这个函数用于从表中选择随机行:

def returnRandom(conn,countcol,table,field):
    cursor = conn.cursor()
    cursor.execute('SELECT MAX(%s) FROM %s',(countcol,table))
    maxRow = cursor.fetchone()[0]
    cursor.execute("SELECT MIN(%s) FROM %s",(countcol,table))
    minRow = cursor.fetchone()[0]
    randomId = random.randrange(minRow,maxRow+1,1)
    cursor.execute("SELECT ? FROM ? WHERE id >=? LIMIT 1",field,table,randomId)
    return cursor.fetchone()[0]

它被称为这样:

msg = funct.returnRandom(conn,"id","testtable","data")

不幸的是它出错了: _mysql_exceptions.ProgrammingError:(1064,“您的SQL语法有错误;请查看与您的MySQL服务器版本对应的手册,以便在第1行的''testtable''附近使用正确的语法”)

如果我将testtable放在执行行上的%s位置,那么查询将会运行,但它看起来像是在运行

SELECT MAX('id') FROM testtable;

当然会返回'id'。

鉴于它们两者在试图执行它们时它看起来像引用%s条目。我想知道是否有人可以解释我是如何让它停止这样做的,或者我应该如何实际做我想要实现的目标?我希望函数尽可能通用,所以依赖于在调用它时传递给它的数据。

编辑:如果我替换,我应该添加?标志:

....
    cursor.execute('SELECT MAX(?) FROM ?',(countcol,table))
File "/usr/lib/pymodules/python2.7/MySQLdb/cursors.py", line 151, in execute
    query = query % db.literal(args)
TypeError: not all arguments converted during string formatting

3 个答案:

答案 0 :(得分:2)

您不能将DB-API用于元数据;您需要在execute()电话之外自行更换。

query = 'SELECT MAX(%%s) FROM `%s`' % (table,)
cursor.execute(query, (countcol,))

如果table来自外部来源,显然你不应该这样做。

答案 1 :(得分:0)

MySQLdb可能用单引号而不是反引号来引用你的表名。试试这个

cursor.execute('SELECT MAX(%%s) FROM `%s`' % table,(countcol))

答案 2 :(得分:-1)

有趣。但在manual中有几个例子。也许它是类似的东西。

c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
          WHERE price < %s""", (max_price,))
  

在这个例子中,max_price = 5为什么在字符串中使用%s?因为MySQLdb会将其转换为SQL文字值,即字符串&#39; 5&#39;。当它完成后,查询实际上会说,&#34; ... WHERE price&lt; 5&#34;

并且

c.executemany(
      """INSERT INTO breakfast (name, spam, eggs, sausage, price)
      VALUES (%s, %s, %s, %s, %s)""",
      [
      ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
      ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
      ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
      ] )
  

这里我们插入三行五个值。请注意,有   混合类型(字符串,整数,浮点数)虽然我们仍然只使用%s。   另请注意,我们只包含一行的格式字符串。   MySQLdb选择那些并为每一行复制它们。