SQL statement failing to execute in Python CGI - python

I have an update statement in my database that is not executing. As far as I am aware, it is syntactically correct. I used this app to verify the syntax. The except block is all that is being executed and I do not understand why.
Here is the code:
for res_posts in list_of_response_ids:
temp_str = res_posts[0] # first element of res_posts tuple is string
temp_str += ":" + str(output[0])
try:
sql = "UPDATE POST SET res_post_id = %s WHERE post_id = %d;" % (str(temp_str), int(res_posts[1]))
cursor.execute(sql)
except:
print "uh oh"
I can post more code if this is not enough information.
EDIT: Following Jacob's advice, I used raise and got the following error:
Traceback (most recent call last):
File "post.cgi", line 93, in <module>
cursor.execute(sql)
File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 173, in execute
self.errorhandler(self, exc, value)
File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':37 WHERE post_id = 8' at line 1")
Thank you so much!

Based on your traceback, there is something wrong with the type of entry you are using for the res_post_id or post_id. Currently you are not passing a representation of the res_post_id string, but a literal string. If res_post_id is a string in your DB Schema, I would recommend using %r like so:
sql = "UPDATE POST SET res_post_id = %r WHERE post_id = %d;" % (str(temp_str), int(res_posts[1]))
This will properly quote your res_post_id value for insertion.
So your statement should change from this:
UPDATE POST SET res_post_id = :37 WHERE post_id = 8;
...to this:
UPDATE POST SET res_post_id = ':37' WHERE post_id = 8;

Related

How Can My sqllite3 interaction be fixed?

I'm trying to get an admin account to edit a 'rank' (basically access level) for one of the profiles in my data-base. The error is:
Traceback (most recent call last):
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 154, in <module>
main()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 9, in main
start_menu()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 22, in start_menu
login()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 72, in login
Mek_menu()
File "U:/A-level Computor Science/Y12-13/SQL/sqlite/Databases/ork task/Python for SQL V_2.py", line 108, in Mek_menu
where Uzaname = %s""" % (NewRank, Findaname))
sqlite3.OperationalError: unrecognized token: "0rk_D4T4B453"`
The code that seems to be the problem is:
cursor.execute(""" update 0rk_D4T4B453.Da_Boyz
set Rank = %s
where Uzaname = %s""" % (NewRank, Findaname))
Originally, it was all on one line and it didn't work, and now I've tried it on multiple lines and it still doesn't work. So I checked here to see if anyone could help.
EDIT1: Thanks for the suggestions. None of them have fixed the code, but I've narrowed the problem code to: where Uzaname = %s""" % (NewRank, Findaname))
Unless you use ATTACH, SQLite (a file-level database) does not recognize other databases. Usually server-level databases (Oracle, Postgres, SQL Server, etc.) use the database.schema.table reference. However, in SQLite the very database file you connect to is the main database in scope. But ATTACH allows you to connect to other SQLite databases and then recognizes database.table referencing.
Additionally, for best practices:
In sqlite3 and any other Python DB-APIs, use parameterization for literal values and do not format values to SQL statement.
In general Python, stop using the de-emphasized (not deprecated yet) string modulo operator, %. Use str.format or more recent F-string for string formatting. But neither is needed here.
Altogether, if you connect to the 0rk_D4T4B453 database, simply query without database reference:
conn = sqlite3.connect('/path/to/0rk_D4T4B453.db')
cursor = conn.cursor()
# PREPARED STATEMENT WITH QMARK PLACEHOLDERS
sql = """UPDATE Da_Boyz
SET Rank = ?
WHERE Uzaname = ?"""
# BIND WITH TUPLE OF PARAMS IN SECOND ARG
cursor.execute(sql, (NewRank, Findaname))
conn.commit()
If you do connect to a different database, call ATTACH. Here also, you can alias other database with better naming instead of number leading identifier.
cursor.execute("ATTACH '/path/to/0rk_D4T4B453.db' AS other_db")
sql = """UPDATE other_db.Da_Boyz
SET Rank = ?
WHERE Uzaname = ?"""
cursor.execute(sql, (NewRank, Findaname))
conn.commit()
cur.execute("DETACH other_db")

Mysql query using python

I'm using python 3.x and mysql.connector to access a Mysql database. I'm having an issuing with querying the database.
When I run the following query, I get the correct result:
cursor.execute("SELECT idx FROM db WHERE name = 'John Smith'")
When I try and run the following query I get an error:
cursor.execute("SELECT idx FROM db WHERE name = %s",'John Smith')
File "<input>", line 1, in <module>
File "C:\Python34\lib\site-packages\mysql\connector\cursor.py", line 515, in execute
self._handle_result(self._connection.cmd_query(stmt))
File "C:\Python34\lib\site-packages\mysql\connector\connection.py", line 488, in cmd_query
result = self._handle_result(self._send_cmd(ServerCmd.QUERY, query))
File "C:\Python34\lib\site-packages\mysql\connector\connection.py", line 395, in _handle_result
raise errors.get_exception(packet)
mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s' at line 1
I've tried running the following query instead, but it appears that the query searches for "%s" not the string "John Smith"
cursor.execute("SELECT idx FROM db WHERE name = '%s'",'John Smith')
I'm not sure if the error is due to the fact that I'm using a string with spaces in it or not, but I haven't been able to solve the problem.
q="SELECT idx FROM db WHERE name = %s";
cursor.execute(q,'Xander')
Formatting just needs to be changed a little. You were pretty close.
foo = 'John Smith'
cursor.execute("SELECT idx FROM db WHERE name = %s", (foo,))
Take a gander at the links below for more explanation
Python MySQL Parameterized Queries
https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-execute.html
According to the docs, you would need to write:
cursor.execute("SELECT idx FROM db WHERE name = %s", ('John Smith'))
In other words, the parameter-replacement values must be contained in an iterable.
(But see the answer from theClap who correctly adds a semi-colon to force "tupleness" where required).

How to pass variable for dropping table execution in Python's MySQLdb

With this code I tried to delete a table if it exists. But I need to do it via passing
a variables.
import MySQLdb as mdb
conn = mdb.connect(host='db01.myhost.co.nl,
user='pdbois',
passwd='triplex',
db='myxxx')
cursor = conn.cursor()
# Without passing variables this works OK!
#cursor.execute("""drop table if exists testtable""")
# But this break
table_name = "testtable"
cursor.execute("""drop table if exists %s""",(table_name))
conn.close()
But why the way I do it above breaks by giving this error?
File "test_mysql.py", line 63, in <module>
main()
File "test_mysql.py", line 59, in main
create_table()
File "test_mysql.py", line 25, in create_table
cursor.execute("""drop table if exists %s""",(table_name))
File "build/bdist.linux-x86_64/egg/MySQLdb/cursors.py", line 174, in execute
File "build/bdist.linux-x86_64/egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''testtable'' at line 1")
What's the right way to do it?
Update:
Another problem is to create a table via parameter.
sql = "create table %s(
first_name char(20) not null,
last_name char(20))" % mdb.escape_string(table_name)
cursor.execute(sql)
It gives `SyntaxError: EOL while scanning string literal`.
You cannot parameterize the table name, use string formatting and escape the value manually:
cursor.execute("drop table if exists %s" % mdb.escape_string(table_name))

Python SQL syntax error

Im trying to run a python script on my raspberry pi, in order to store the data that I receive from the gps receiver into a sql table. While Im executing this script I'm getting an error on this part of the code:
sql = "INSERT INTO gps (n_lat, w_long, date_time) VALUES (%s, %s, %s)" % (north, west, t,)
print sql
cur.execute(sql)
print "Rows inserted: %s" % cur.rowcount
con.commit()
time.sleep(0.5)
Error:
Traceback (most recent call last):
File "gps.py", line 48, in <module>
cur.execute(sql)
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.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':01:16)' at line 1")
I don't really understand where is the problem, Have you got any ideas why whiz error occurs ?
You did not escape your input values. For numbers this is optional, but datetime might not be a number.
However, you should always escape input values for your database. The keyword here is prepared statements. Instead of parsing your input arguments into the string with pythons % operater, you should use the argument list of cursor.execute.
sql = "INSERT INTO gps (n_lat, w_long, date_time) VALUES (%s, %s, %s)"
print sql
cur.execute(sql, (north, west, t,))
print "Rows inserted: %s" % cur.rowcount
con.commit()
time.sleep(0.5)
Now the function execute will make sure, that all special characters are escaped. E.g. one of your input values might contain a single quote or similar. Using python's string parsing, this would result in something like:
"INSERT INTO gps (n_lat, w_long, date_time) VALUES ('123', '123', '1234'321')"
In best case this would result in a database error, in worst case somebody could manipulate your database with his own SQL statements (so called SQL injection).
The error in the SQL statement you have set values inside a quote:
VALUES ('%s', '%s', '%s')

pass table name as parameter in postgres via python

I want to execute postgres query in python.The table name has to be passed as a parameter.Since the table will be created at run time. I have used dict query param style.But i am getting an error.
import psycopg2
CONNECTION_STRING = "dbname='autogist' user='postgres' password=''"
query = "INSERT INTO %(table)s " +\
"(vin_id, vin_details_id, price, mileage, dealer_id, created_on, modified_on) " +\
"VALUES (%(vin_id)s, %(vlookup_id)s, %(price)s, %(mileage)s, %(dealer_id)s,now(),now()) " +\
"RETURNING id"
params = {"table" : "dealer_vehicle_details_2010_01_02",\
"vin_id":"3",\
"vlookup_id":"403",\
"price":"403",\
"mileage":"403",\
"dealer_id":"276092"
}
conn=psycopg2.connect(CONNECTION_STRING)
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
cursor.execute(query,params)
TRACEBACK:
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (262, 0))
---------------------------------------------------------------------------
ProgrammingError Traceback (most recent call last)
/home/gridlex/workspace/<ipython console> in <module>()
/usr/local/lib/python2.6/dist-packages/psycopg2/extras.pyc in execute(self, query, vars)
121 self.index = {}
122 self._query_executed = 1
--> 123 return _cursor.execute(self, query, vars)
124
125 def callproc(self, procname, vars=None):
ProgrammingError: syntax error at or near "E'dealer_vehicle_details_2010_01_02'"
LINE 1: INSERT INTO E'dealer_vehicle_details_2010_01_02' (vin_id, vi...
The statement you send must be syntactically valid when PREPAREd, which a statement with placeholders for table names is not. You can't use placeholders for table names in prepared statements.
Your options are:
Substitute the table name in with regular string substitution, "double quoted". Be very careful with your quoting routine; make sure it doubles any quotes within the table name its self, so the table name double"quote becomes "double""quote". Eg. 'SELECT * FROM "%s"' % quote_ident(tablename). You'd have to roll your own quote_ident as AFAIK psycopg2 doesn't expose a function like that.
Send the table name as a query parameter to a PL/PgSQL function that uses EXECUTE ... USING to create a dynamic SQL statement using the table name. PL/PgSQL can use the quote_ident function to provide safer quoting than a home-rolled implementation.

Categories