我正在尝试使用以下代码插入包含int和string的VALUES:
def log_summoner(summonerId):
c = ['profileIconId', 'summonerLevel', 'revisionDate', 'id', 'name']
v = summonerId.values()
con = connect(MYSQL['HOST'], MYSQL['USER'], MYSQL['PASSWORD'], MYSQL['DB'], charset='utf8')
with con:
cur = con.cursor()
q = "INSERT IGNORE INTO "
q += "summoners({0},{1},{2},{3},{4}) "
q += "VALUES({5},{6},{7},{8},{9})"
print 'c = ', c
print 'v = ', v
cur.execute(q.format(*(c+v)))
我收到以下输出和错误:
c = ['profileIconId', 'summonerLevel', 'revisionDate', 'id', 'name']
v = [627, 30, 1398712111000, 60783, u'TheOddOne']
Traceback (most recent call last):
File "./game_crawler.py", line 245, in <module>
log_summoner(s)
File "./game_crawler.py", line 172, in log_summoner
cur.execute(q.format(*(c+v)))
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.OperationalError: (1054, "Unknown column 'TheOddOne' in 'field list'")
以下是表汇总器的描述:
mysql> DESCRIBE summoners;
+---------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| name | varchar(255) | NO | | NULL | |
| profileIconId | smallint(6) | NO | | NULL | |
| revisionDate | bigint(20) | NO | | NULL | |
| summonerLevel | tinyint(4) | NO | | NULL | |
+---------------+--------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
如果我将'TheOddOne'更改为int,它将起作用。我究竟做错了什么?提前谢谢!
答案 0 :(得分:0)
您应该将'TheOddOne'作为字符串插入。为此,只需在{9}中添加引号:
q += "VALUES({5},{6},{7},{8},'{9}')"
但是这种方法很容易被sql注入。请考虑以下示例:
#Testing SQL Injection
print 'Testing SQL Injection'
c = ['\' or 1 = 1 or \'']
q = "SELECT * FROM summoners WHERE name = '{0}'"
query = q.format(*c)
print query
cursor.execute(query)
if cursor.rowcount > 0:
print cursor.fetchall()
else:
print "no item found"
这将为我们提供所有记录。
最佳解决方案 - 使用如下参数化查询:
q = "INSERT IGNORE INTO summoners (profileIconId, summonerLevel, revisionDate, id, name) VALUES (%s,%s,%s,%s,%s) "
cursor.execute(q, v)
但是,由于您需要动态插入列名称,为您提供适当的解决方案 - 将参数化查询与MySQLdb.escape_string
相结合:
q = "INSERT IGNORE INTO summoners({0},{1},{2},{3},{4}) VALUES (%s,%s,%s,%s,%s)".format(*c)
query = MySQLdb.escape_string(q)
cursor.execute(query, v)