在MySQL表名周围插入单引号(')的Python方法

4 投票
3 回答
2538 浏览
提问于 2025-04-17 17:22

我有一个叫做project1的数据库,里面有以下几个表:

_systbl1
_systbl2
_systbl3
dataset1
dataset2
dataset3

MySQL用户odbc在每次添加新表时,需要被授予对dataset%表的SELECT权限。

为了解决这个问题,我写了一个简单的Python脚本,像这样:

#!/usr/bin/python
import MySQLdb

db = MySQLdb.connect(
    host="localhost",
    user="user",
    passwd="pass",
    db="project1"
    )

    # Create Cursor Object
cur = db.cursor()

# get list of tables beginning with dataset
cur.execute("SHOW TABLES FROM project1 LIKE 'dataset%';")

# run GRANT statement for each table
for row in cur.fetchall() :
    cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`@`localhost`;", row)
    cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`@`%`;", row)

不幸的是,它给了我以下错误:

Traceback (most recent call last):
  File "mysql_query.py", line 20, in <module>
    cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`@`localhost`;", row)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.ProgrammingError: (1146, "Table 'project1.'dataset1'' doesn't exist")

从错误的最后一行可以看到,问题在于Python在生成查询时,把表名用单引号括起来了。

我这里缺少了什么呢?

3 个回答

1

在编程中,有时候我们会遇到一些问题,尤其是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,但其实很多时候,解决这些问题的方法都在网上,比如StackOverflow这样的社区。

在这些社区里,很多人会分享他们遇到的问题和解决方案。你可以看到其他人是怎么描述他们的问题的,以及他们是如何找到解决办法的。这些信息对于我们学习编程非常有帮助。

如果你在编程过程中遇到困难,不妨去这些社区看看,可能会找到你需要的答案。

sql = """CREATE TABLE IF NOT EXISTS `""" + project +  """` ( `id` INT(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`))"""
1

可以改用:

cur.execute("GRANT SELECT ON `project`.`%s` TO `odbc`@`localhost`" % row)

这样做不会对输入进行正常的转义处理。不过,要注意你的表名中如果有反引号(`)的话,可能会出问题。

2

不要把表名当作SQL参数来使用。SQL参数是由数据库适配器处理的,它们只会被当作字面值来理解,不会被当作其他东西。

你需要自己把表名插入到SQL语句中,但一定要确保你的表名里没有不可信的数据(这样可以防止SQL注入攻击):

cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`@`localhost`;" % row)
cur.execute("GRANT SELECT ON `project1`.`%s` TO `odbc`@`%%`;" % row)

(在这里,%字符在授权中被通过重复来转义成%%)。

撰写回答