你如何使用MySQLdb插入int和字符串VALUES到MySQL?

时间:2014-04-29 17:42:44

标签: python mysql mysql-python

我正在尝试使用以下代码插入包含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,它将起作用。我究竟做错了什么?提前谢谢!

1 个答案:

答案 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)