Question

I am trying to INSERT VALUES that contain both int and string using the code below:

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

I am receiving this following output and error:

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'")

Here is the description of the table summoners:

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)

If I changed 'TheOddOne' to an int it will work. What am I doing wrong? Thank you in advance!

Was it helpful?

Solution

You should insert 'TheOddOne' as a string. To do this, simply add quotes to {9}:

q += "VALUES({5},{6},{7},{8},'{9}')"

But this method is prone to sql injection. Consider follow example:

#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"

This will give us all the records.

The best solution - use parameterized queries like this:

q = "INSERT IGNORE INTO summoners (profileIconId, summonerLevel, revisionDate, id, name) VALUES   (%s,%s,%s,%s,%s) "
cursor.execute(q, v)

However, since you need to dynamically insert column names, appropriate solution for you - combining parameterized queries with 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)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top