I'v searched throughout this forum and couldn't find an answer.
cur.execute("UPDATE lastran SET job_date=newtimedate WHERE job_name=usrjobname")
Why is my code now working?
The two variables are newtimedate and usrjobname
I don't know Python, but it seems you're passing your variables as literals... a little Googling tells me this should be it?
cur.execute("UPDATE lastran SET job_date=? WHERE job_name=?", (newtimedate, usrjobname))
See how this person does it: How to see the real SQL query in Python cursor.execute
Related
This question already has answers here:
How to use variables in SQL statement in Python?
(5 answers)
Closed 2 months ago.
def update_inv_quant():
new_quant = int(input("Enter the updated quantity in stock: "))
Hello! I'm wondering how to insert a user variable into an sql statement so that a record is updated to said variable. Also, it'd be really helpful if you could also help me figure out how to print records of the database into the actual python console. Thank you!
I tried doing soemthing like ("INSERT INTO Inv(ItemName) Value {user_iname)") but i'm not surprised it didnt work
It would have been more helpful if you specified an actual database.
First method (Bad)
The usual way (which is highly discouraged as Graybeard said in the comments) is using python's f-string. You can google what it is and how to use it more in-depth.
but basically, say you have two variables user_id = 1 and user_name = 'fish', f-string turns something like f"INSERT INTO mytable(id, name) values({user_id},'{user_name}')" into the string INSERT INTO mytable(id,name) values(1,'fish').
As we mentioned before, this causes something called SQL injection. There are many good youtube videos that demonstrate what that is and why it's dangerous.
Second method
The second method is dependent on what database you are using. For example, in Psycopg2 (Driver for PostgreSQL database), the cursor.execute method uses the following syntax to pass variables cur.execute('SELECT id FROM users WHERE cookie_id = %s',(cookieid,)), notice that the variables are passed in a tuple as a second argument.
All databases use similar methods, with minor differences. For example, I believe SQLite3 uses ? instead of psycopg2's %s. That's why I said that specifying the actual database would have been more helpful.
Fetching records
I am most familiar with PostgreSQL and psycopg2, so you will have to read the docs of your database of choice.
To fetch records, you send the query with cursor.execute() like we said before, and then call cursor.fetchone() which returns a single row, or cursor.fetchall() which returns all rows in an iterable that you can directly print.
Execute didn't update the database?
Statements executing from drivers are transactional, which is a whole topic by itself that I am sure will find people on the internet who can explain it better than I can. To keep things short, for the statement to physically change the database, you call connection.commit() after cursor.execute()
So finally to answer both of your questions, read the documentation of the database's driver and look for the execute method.
This is what I do (which is for sqlite3 and would be similar for other SQL type databases):
Assuming that you have connected to the database and the table exists (otherwise you need to create the table). For the purpose of the example, i have used a table called trades.
new_quant = 1000
# insert one record (row)
command = f"""INSERT INTO trades VALUES (
'some_ticker', {new_quant}, other_values, ...
) """
cur.execute(command)
con.commit()
print('trade inserted !!')
You can then wrap the above into your function accordingly.
I'm using python module sqlite3 as per the below code:
# Enter the randomised data into the dictionary:
for square in cube:
cur.execute("UPDATE cubes SET ? = ? WHERE id = ?", (square, cube[square], session["current_cube_id"]))
con.commit()
Which results in the following error:
cur.execute("UPDATE cubes SET ? = ? WHERE id = ?", (square, cube[square], session["current_cube_id"]))
sqlite3.OperationalError: near "?": syntax error
I don't seem to have a problem with INSERT or SELECT queries, so I assume there is a specific syntax required to UPDATE. From the documentation, tutorials and other examples I can find this seems to be correct - can anyone please assist with what might be the syntax error?
You can't define table, column names, or SQL keywords, using bind variables (the SET ? =) in UPDATE cubes SET ? = ? WHERE id = ?
I am not sure why you feel you need to have a dynamic column name, rather than UPDATE cubes SET mycol = ? WHERE id = ? but you need to specify your column name differently.
You'd have the exact same problem with insert or delete if your target column names, in an insert, or your where condition column names in a delete, were getting specified with ? placeholders. I assume you did not do this so you did not get the error.
Be very careful if you decide to build your query string dynamically as in
myquery = f"UPDATE cubes SET {my_user_supplied_column_name} = ? WHERE id = ?"
cur.execute(myquery, (cube[square], session["current_cube_id"]))
That opens you to a large class of extremely serious vulnerabilities, the SQL Injections because the user may enter anything they want in my_user_supplied_column_name. Best to be very careful as it also has a reputational risk: a savvy prospective employer might for example reject your application if they saw this type of construct, unguarded, in your code because it is an extremely grave, frequent and well-known risk.
I'm fairly new to Python but have a project I am working on so please excuse any nativity on my part.
I am writing some SQL statements in Python 2.7 (Libraries not upgraded to 3 yet) but I am getting stuck on best practice procedure for them. We are using Sybase. Initially I was using
query = "UPDATE DB..TABLE SET version = '{}' WHERE name = '{}'".format(app.version, app.name)
cursor.execute(query)
But realised this after further reading that it is open to injection. So I then looked at doing the following:
query = "UPDATE DB..TABLE SET version = '%s' WHERE name = '%s'" % (app.version, app.name)
cursor.execute(query)
But got me to thinking is this not the same thing?
The parameters are also variables set by argparse, which means I have to use the '' around %s otherwise it throws up the invalid column name error. Which is frustrating for me as I also want to be able to pass NULL (None in Python) by default if any additional flags aren't set in other queries, otherwise it obviously inserts "NULL" as string.
For this particular example the 2 variables are set from a file being read by ConfigParser but I think it's still the same for argparse variables. e.g.
[SECTION]
application=name
version=1.0
I'm not quite sure how to best tackle this issue and yes yes I know "PYTHON 3 IS BETTER UPGRADE TO IT", as I said at the start, the libraries are in the process of being ported.
If you need any additional info then please advise and I will give you the best I can.
UPDATE***
Using the following Param style string I found in some sybase docs it can work but it does not pass None for NULL and throws up errors, starting to think this is a limitation of the sybase module in python.
cursor.execute("SELECT * FROM DB..table where app_name=#app_name", {"#app_name": app_name})
or
params = {"#appname": app.name. "#appver": app.version}
sql = "INSERT INTO DB..table (app_name, app_version) VALUES (#appname, #appversion)
cursor.execute(sql, params)
There is an issue though if you have a global list of params and feed that to a query that if any are None then it gives you a lot of errors again about being None, EVEN if those specific params aren't used in the query. Think I may be stuck doing IF statements for various options here for multiple inserts to bypass this None NULL issue.
Ok I have resolved this issue now.
I had to update the sybase module in order to get it to work with None > NULL.
As posted in the updated question. the below is how I was running the queries.
cursor.execute("SELECT * FROM DB..table where app_name=#app_name", {"#app_name": app_name})
or
params = {"#appname": app.name. "#appver": app.version}
sql = "INSERT INTO DB..table (app_name, app_version) VALUES (#appname, #appversion)
cursor.execute(sql, params)
But got me to thinking is this not the same thing?
Yes, those are effectively the same. They are both wide open to an injection attack.
Instead, do it this way:
query = "UPDATE DB..TABLE SET version = %s WHERE name = %s"
cursor.execute(query, [app.version, app.name])
When I make a MySQL table order, it is created successfully but, when I execute any query against it, it says "error 1064 , syntax error".
When I change the name to orders, it works fine.
But I don't want to change the name. How can I execute our query against the order table?
can you use something like?
select * from `order`
The word order is actually an SQL keyword. You would have the same problem if you tried to use a table called group or select. You can fix it is MySQL by using quotes around it, along the lines of:
select f1, f2 from `order` where blah blah blah ...
However, unless your table will only ever hold a single order (in which case it won't do so for long since the underlying business will soon be bankrupt), you should probably call your table orders.
That solves both your problems, the one you found and the one you didn't :-)
I got here because I was searching for similar solution for SQL CE. There using
order
'order'
"order"
doesn't work.
What worked was:
[order]
Maybe it'll help someone else also.
This should fix the problem:
e.g
mysql>
Create table order(
ID char(5),
QTY(3)
)
;
Question: Why is this sqlite3 statement not updating the record?
Info:
cur.execute('UPDATE workunits SET Completed=1 AND Returns=(?) WHERE PID=(?) AND Args=(?)',(pickle.dumps(Ret),PID,Args))
I'm using python and sqlite3. this statement does not throw an error, it just seems like it is out right ignored. for testing reasons I included below it:
cur.execute('SELECT * FROM workunits WHERE PID=(?) AND Args=(?)',(PID,Args))
Which returns a record just fine. but the record doesn't up date with the new value of the pickled ret. it remains u''. I can't figure out why. my where statement seems to work. my syntax seems to be correct because there is no error being thrown. I'm clueless as to why exactly it doesn't work.
If the problem persists after you fixed your syntax. Please make sure you're using:
conn.commit()
After cur.execute, UPDATES and INSERTS require COMMIT.
don't use 'AND', use a ','.
cur.execute('UPDATE workunits SET Completed=1, Returns=? WHERE PID=? AND Args=?',
(pickle.dumps(Ret), PID, Args)
)