3

I'm making a little imageboard kind of thing, and I'm trying to do a MySQL insert, but this piece of code is throwing an error:

curs.execute("INSERT INTO posts(date,replies,title,link,text,userip,username) VALUES('{}',{},'{}','{}','{}','{}','{}');".format((self.date.isoformat(),self.replies,self.title,self.embed,self.text,self.userip,self.username)))

And here's the error (running this on top of Falcon/WSGI):

2015-05-05 17:37:14,135 :Traceback (most recent call last):
2015-05-05 17:37:14,136 :  File "/bin/user_wsgi_wrapper.py", line 130, in __call__
2015-05-05 17:37:14,136 :    self.error_log_file.logger.exception("Error running WSGI application")
2015-05-05 17:37:14,136 :  File "/usr/lib/python2.7/logging/__init__.py", line 1185, in exception
2015-05-05 17:37:14,136 :    self.error(msg, *args, **kwargs)
2015-05-05 17:37:14,136 :  File "/usr/lib/python2.7/logging/__init__.py", line 1178, in error
2015-05-05 17:37:14,136 :    self._log(ERROR, msg, args, **kwargs)
2015-05-05 17:37:14,136 :  File "/usr/lib/python2.7/logging/__init__.py", line 1270, in _log
2015-05-05 17:37:14,137 :    record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
2015-05-05 17:37:14,137 :  File "/usr/lib/python2.7/logging/__init__.py", line 1244, in makeRecord
2015-05-05 17:37:14,137 :    rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
2015-05-05 17:37:14,137 :  File "/usr/lib/python2.7/logging/__init__.py", line 284, in __init__
2015-05-05 17:37:14,137 :    self.threadName = threading.current_thread().name
2015-05-05 17:37:14,137 :  File "/usr/lib/python2.7/threading.py", line 1160, in currentThread
2015-05-05 17:37:14,137 :    return _active[_get_ident()]
2015-05-05 17:37:14,137 :  File "/bin/user_wsgi_wrapper.py", line 122, in __call__
2015-05-05 17:37:14,138 :    app_iterator = self.app(environ, start_response)
2015-05-05 17:37:14,138 :  File "/home/isitcoldinfallschurch/.virtualenvs/myvirtualenv/local/lib/python2.7/site-packages/falcon/api.py", line 175, in __call__
2015-05-05 17:37:14,138 :    responder(req, resp, **params)
2015-05-05 17:37:14,138 :  File "./new.py", line 89, in on_post
2015-05-05 17:37:14,139 :    thispost.insertdb()
2015-05-05 17:37:14,139 :  File "./new.py", line 57, in insertdb
2015-05-05 17:37:14,140 :    curs.execute("INSERT INTO posts(date,replies,title,link,text,userip,username) VALUES('{}',{},'{}','{}','{}','{}','{}');".format((self.date.isoformat(),self.replies,self.title,self.embed,self.text,self.userip,self.username)))
2015-05-05 17:37:14,140 :IndexError: tuple index out of range

How can I correct this?

3
  • 1
    Your second set of` { } are missing single quotes VALUES('{}',{},'{}','{}','{}','{}','{}') Commented May 5, 2015 at 17:55
  • 2
    Why are you creating another tuple? Simply do format(self.date.isoformat(),self.replies,self.title,self.embed,self.text,self.userip,self.username) Commented May 5, 2015 at 17:55
  • 1
    @Cyber If the value is actually a number, then you don't need them I guess Commented May 5, 2015 at 17:57

1 Answer 1

3

You have extra brackets in your .format input which is doing this (treating the inputs as a single tuple).

Proof of concept:

>>> "{}{}".format((1,2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: tuple index out of range
>>> "{}{}".format(1,2)
'12'

So instead of this

curs.execute("INSERT INTO posts(date,replies,title,link,text,userip,username) VALUES('{}',{},'{}','{}','{}','{}','{}');".format((self.date.isoformat(),self.replies,self.title,self.embed,self.text,self.userip,self.username)))

do this

curs.execute("INSERT INTO posts(date,replies,title,link,text,userip,username) VALUES('{}',{},'{}','{}','{}','{}','{}');".format(self.date.isoformat(),self.replies,self.title,self.embed,self.text,self.userip,self.username))

As @chepner notes in the comments below, a better way to do this would be to use the below, where the %s are filled by the cursor using the tuple passed as the second argument to execute:

curs.execute("INSERT INTO posts(date,replies,title,link,text,userip,username) VALUES(%s, %s, %s, %s, %s, %s, %s);", (self.date.isoformat(), self.replies, self.title, self.embed, self.text, self.userip, self.username))
Sign up to request clarification or add additional context in comments.

9 Comments

I don't know what type curs is, but I strongly suspect the OP should not be using format at all to generate the SQL statement.
Something like curs.execute("INSERT INTO posts(date,replies,title,link,text,userip,username) VALUES(%s, %s, %s, %s, %s, %s, %s);", (self.date.isoformat(), self.replies, self.title, self.embed, self.text, self.userip, self.username))
@chepner You are right, the type can not be accurately inferred, though I think it is a cursor; curs can be short for cursor and it has the .execute method as well.
Because with format, a value with a single quote will change the parsing of the statement passed to MySQL. Use the cursor to provide properly quoted parameters; don't try to generate the SQL string dynamically.
Notice I'm not using the Python % string operator; the %s are filled by the cursor using the tuple passed as a second argument to execute.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.