使用Python dbapi转义MySQL保留字

时间:2012-05-16 11:34:10

标签: python mysql mysql-python python-db-api

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

我有以下代码:

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实现这一目标?

2 个答案:

答案 0 :(得分:2)

也许这会奏效:

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

UPDATE :这似乎不起作用,因为这种方式的绑定参数会添加单引号,因为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)

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

答案 1 :(得分:0)

来自here

  

您可以使用%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会根据需要为您提供报价。
  •   
  • 在execute()的语句字符串参数之后,按照它们应出现在字符串中的顺序,提供一个包含要绑定到占位符的值的元组。如果只有一个值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)