【发布时间】:2014-04-30 17:31:09
【问题描述】:
我尝试以文章Python MySQLdb execute table variable 为例,但到目前为止还没有任何乐趣。我正在尝试创建一个表,其名称是“存档”的串联,并且作为变量传入的年份。这是硬编码表名称的替代方法,例如“archive_2013”。
这是我的代码 sn-p:
year_string = sys.argv[1]
if int(year_string) < 1999 or int(year_string) > 2014:
print "\n"
print "Year must be between 1999 and 2014\n"
sys.exit(1)
table_name = "archive_" + year_string
# Open database connection
db = MySQLdb.connect("localhost","root","menagerie","haiku_archive" )
# prepare a cursor object using cursor() method
cursor = db.cursor()
# Create table using execute() method.
sql = ""CREATE TABLE IF NOT EXISTS %s" % table_name
haiku_text VARCHAR(120),
date_written CHAR(22))"
cursor.execute(sql)
这是我得到的错误:
pablo@desktop=> ./insert_haiku_from_file_into_table.py 2013 qwert.txt
File "./insert_haiku_from_file_into_table.py", line 36
sql = ""CREATE TABLE IF NOT EXISTS %s" % table_name
^
SyntaxError: invalid syntax
任何帮助将不胜感激!
我尝试实施收到的回复,但到目前为止效果并不理想。这是我使用三引号 SQL 的 sn-p:
sql = """CREATE TABLE IF NOT EXISTS %
haiku_text VARCHAR(120),
date_written CHAR(22))""" % table_name
cursor.execute(sql)
当我执行脚本时,我最终得到以下信息:
pablo@desktop=> ./insert_haiku_from_file_into_table.py 2013 qwert.txt
Traceback (most recent call last):
File "./insert_haiku_from_file_into_table.py", line 38, in <module>
date_written CHAR(22))""" % table_name
ValueError: unsupported format character '
' (0xa) at index 28
我还尝试使用占位符表示法,因为我想避免 SQL 注入的最遥远的可能性。这是我的 sn-p:
sql = """CREATE TABLE IF NOT EXISTS ?
haiku_text VARCHAR(120),
date_written CHAR(22))"""
cursor.execute(sql, table_name)
这是我执行时发生的情况:
pablo@desktop=> ./insert_haiku_from_file_into_table.py 2013 qwert.txt
Traceback (most recent call last):
File "./insert_haiku_from_file_into_table.py", line 39, in <module>
cursor.execute(sql, table_name)
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 159, in execute
query = query % db.literal(args)
TypeError: not all arguments converted during string formatting
我将进一步研究占位符的语法,但同时任何进一步的建议都会很棒!
【问题讨论】:
-
不要不使用字符串格式来参数化 SQL 查询。否则你会插入一个严重的安全漏洞:SQL injection。您可以放置一个占位符并将参数传递给光标的
execute方法:sql = """CREATE TABLE IF NOT EXISTS ? etc. """; cursor.execute(sql, table_name)。您可以检查全局占位符的语法:MySQLdb.paramstyle。有关详细信息,请参阅spec。 -
我没有考虑过 SQL 注入的困境,因为变量是由另一个 python 脚本传入的,但我认为最好完全避免它。感谢您的提醒!
-
@Bakuriu 参数不能用于表名,只能在允许表达式的地方使用。
-
我在其他地方听说参数不能用于表名。我希望情况并非如此。