我正在寻找一个很好的“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实现这一目标?
答案 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)