简体   繁体   中英

dynamic table mysqldb python string/int issue

I am receiving an error when trying to write data to a database table when using a variable for the table name that I do not get when using a static name. For some reason on the line where I insert, if I insert an integer as the column values the code runs and the table is filled, however, if I try to use a string I get a SQL syntax error

cursor = db.cursor()
cursor.execute('DROP TABLE IF EXISTS %s' %data[1])

sql ="""CREATE TABLE %s  (IP TEXT, AVAILIBILITY INT)""" %data[1]
cursor.execute(sql)

for key in data[0]:
    cur_ip = key.split(".")[3]
    cursor.execute("""INSERT INTO %s VALUES (%s,%s)""" %(data[1],key,data[0][key]))  
    db.commit()

the problem is where I have %(data[1], key, data[0][key]) any ideas?

It's a little hard to analyse your problem when you don't post the actual error, and since we have to guess what your data actually is. But some general points as advise:

Using a dynamic table name is often not way DB-systems want to be used. Try thinking if the problem could be used by using a static table name and adding an additional key column to your table. Into that field you can put what you did now as a dynamic table name. This way the DB might be able to better optimize your queries, and your queries are less likely to get errors (no need to create extra tables on the fly for once, which is not a cheap thing to do. Also you would not have a need for dynamic DROP TABLE queries, which could be a security risk.

So my advice to solve your problem would be to actually work around it by trying to get rid of dynamic table names altogether.

Another problem you have is that you are using python string formatting and not parameters to the query itself. That is a security problem in itself (SQL-Injections), but also is the problem of your syntax error. When you use numbers, your expression evaluates to

INSERT INTO table_name VALUES (100, 200)

Which is valid SQL. But with strings you get

INSERT INTO table_name VALUES (Some Text, some more text)

which is not valid (since you have no quotes ' around the strings.

To get rid of your syntax problem and of the sql-injection-problem, don't add the values to the string, pass them as a list to execute() :

cursor.execute("INSERT INTO table_name VALUES (%s,%s)", (key, data[0][key]))

If you must have a dynamic table name, put that in your query string first (eg with % formatting), and give the actual values for your query as parameters as above (since I cannot imagine that execute will accept the table name as a parameter).

To put it in some simple sample code. Right now you are trying to do it like this:

# don't do this, this won't even work!
table_name = 'some_table'
user_name = 'Peter Smith'
user_age = 47
query = "INSERT INTO %s VALUES (%s, %s)" % (table_name, user_name, user_age)
cursor.execute(query)

That creates query

INSERT INTO some_table VALUES (Peter Smith, 100)

Which cannot work, because of the unquoted string. So you needed to do:

# DON'T DO THIS, it's bad!
query = "INSERT INTO %s VALUES ('%s', %s)" % (table_name, user_name, user_age)

That's not a good idea, because you need to know where to put quotes and where not (which you will mess up at some point). Even worse, imagine a user named named Connor O'Neal . You would get a syntax error:

INSERT INTO some_table VALUES ('Connor O'Neal', 100)

(This is also the way sql-injections are used to crush your system / steal your data). So you would also need to take care of escaping the values that are strings. Getting more complicated.

Leave those problems to python and mysql, by passing the date (not the table name) as arguments to execute!

table_name = 'some_table'
user_name = 'Peter Smith'
user_age = 47
query = "INSERT INTO " + table_name + " VALUES (%s, %s)"
cursor.execute(query, (user_name, user_age))

This way you can even pass datetime objects directly. There are other ways to put the data than using %s , take a look at this examples http://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html (that is python3 used there, I don't know which you use - but except of the print statements it should work with python2 as well, I think).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM