0

我正在为 MySQL 中的保留字问题寻找一个不错的“pythonic”和“SQL-Injection-free”解决方案。

我有以下代码:

alter_sql = 'ALTER TABLE %s ADD COLUMN %s TEXT'      
cursor.execute(alter_sql, sql_params)

当列名类似于 'index'、'int'、'limit' ...时,就会出现问题。

在 MySQL shell 中,我可以这样做:

ALTER TABLE test ADD COLUMN test.limit;

或者

ALTER TABLE test ADD COLUMN `limit`;

但不是

ALTER TABLE test ADD COLUMN 'test.limit';

如何使用 Python 和 MySQLdb 实现这一目标?

4

2 回答 2

2

也许这会起作用:

alter_sql = 'ALTER TABLE `%s` ADD COLUMN `%s` TEXT'

更新:这似乎不起作用,因为以这种方式绑定参数将添加单引号,因为 MySQLdb 假设这是一个字符串文字。

或者,您可以在列名之前附加表名?

table_name = MySQLdb.escape_string(table_name)
escaped_column_name = MySQLdb.escape_string(column_name)
column_name = '`%s`.`%s`' % (table_name, escaped_column_name)

alter_sql = 'ALTER TABLE %s ADD COLUMN %s TEXT' % (table_name, column_name)

这样,您必须手动转义它们,以避免绑定它们并在其周围添加单引号。

于 2012-05-16T11:35:45.977 回答
0

这里

您可以通过使用 %s 占位符标记并将适当的值绑定到它们来发出相同的语句:

cursor.execute("""UPDATE animal SET name = %s
                  WHERE name = %s
               """, ("snake", "turtle"))
print "Number of rows updated: %d" % cursor.rowcount

关于前面的 execute() 调用的形式,请注意以下几点:

  • 对于要插入语句字符串的每个值,%s 占位符标记应出现一次。
  • %s 标记周围不应加引号;MySQLdb 根据需要为您提供报价。
  • 在执行()的语句字符串参数之后,提供一个包含要绑定到占位符的值的元组,按照它们应该出现在字符串中的顺序。如果您只有一个值 x,请将其指定为 (x,) 以指示单元素元组。
  • 将 Python None 值绑定到占位符以将 SQL NULL 值插入到语句中。

因此,基于此,您应该只预处理您的参数以查看它们是否在保留关键字列表中,如果是,请将表名添加到列名的前面,例如。

RESERVED_KEYWORDS = ['LIMIT', 'INT', 'INDEX']
table_name = 'TESTING'
column_name = 'LIMIT'
if column_name in RESERVED_KEYWORDS:
    column_name = '%s.%s' % (table_name, column_name)
sql_params = [table_name, column_name]
alter_sql = 'ALTER TABLE %s ADD COLUMN %s TEXT'      
cursor.execute(alter_sql, sql_params)
于 2012-05-16T12:00:45.880 回答