Use Python variable in a MySQL Subquery - python

team = input("Enter the team name: ")
cursor = db.cursor()
sql = "SELECT * FROM `flash_data_archive` WHERE `event_id` IN (SELECT `alternate_id` from `event_list` where `category` = %s)" % team
cursor.execute(sql)
What is the correct notation to have the the string the user entered for 'team' to be used for the category field in the sql subsuery?

Remove the % team from the string. Instead, it should be an argument to .execute.
cursor.execute(sql, team)
This will properly escape it.

Related

How to use an UPDATE SQL statement with user input from Python?

I'm new to Python and especially to SQL.
My goal is:
A user should enter which phone number he wants to change
Then the user should be able to enter the new phone number
This change should then be stored in my MySQL database
As I know the syntax for an update is like this:
sql = "UPDATE table SET fieldname = value" "WHERE fieldname = value"
But if I try to use the code with two variables from an input, it doesn't work:
input_change = input("Write the number to change: ")
input_new = input("Write the new number: ")
sql = "UPDATE table SET telefonnummer = ?" "WHERE telefonnummer = ?"
cursor.execute(sql, (input_change, input_new))
connection.commit()
Does somebody have an idea how I can fix this? Or where can I find a good description about using variables in SQL statements?
Many thanks for the answers.
Change :
sql = "UPDATE table SET telefonnummer = ?" "WHERE telefonnummer = ?"
to
sql = "UPDATE table SET telefonnummer = ? WHERE telefonnummer = ?"
and
cursor.execute(sql, (input_change, input_new))
to
cursor.execute(sql, [input_change, input_new])

How to escape the % and \ signs in pymysql using LIKE clause?

I want to find something like "probability: 10%" or "10% high" in my 'events' column, but when I used the code below:
conn = pymysql.connect(host="localhost", port=3306, user='myid', passwd='mypwd', db='mydb', charset='utf8')
curs = conn.cursor()
key = "%"
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE %s",
("%" + key + "%",)
)
it returned every row in the table. It executed this query:
SELECT count(*) AS number FROM city WHERE events LIKE '%%%'
like this, which I didn't intend.
Searching for the backslash sign also gave me incorrect results.
What should I do to get the correct result?
Thanks in advance.
instead of the concat the wildchar in param you could use concat in SQL and pass the value
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE CONCAT('%', %s, '%')",
(key ,)
)
or as uggested by #Notinlist
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE CONCAT('%%', %s, '%%')",
(key ,)
)
You ought to use SQL ESCAPE clause:
curs.execute(
"SELECT count(*) AS number FROM city WHERE events LIKE '%#%%' ESCAPE '#'"
)

use row as variable with python and sql

I am trying to update some values into a database. The user can give the row that should be changed. The input from the user, however is a string. When I try to parse this into the MySQL connector with python it gives an error because of the apostrophes. The code I have so far is:
import mysql.connector
conn = mysql.connector
conn = connector.connect(user=dbUser, password=dbPasswd, host=dbHost, database=dbName)
cursor = conn.cursor()
cursor.execute("""UPDATE Search SET %s = %s WHERE searchID = %s""", ('maxPrice', 300, 10,))
I get this error
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 ''maxPrice' = 300 WHERE searchID = 10' at line 1
How do I get rid of the apostrophes? Because I think they are causing problems.
As noted, you can't prepare it using a field.
Perhaps the safest way is to allow only those fields that are expected, e.g.
#!/usr/bin/python
import os
import mysql.connector
conn = mysql.connector.connect(user=os.environ.get('USER'),
host='localhost',
database='sandbox',
unix_socket='/var/run/mysqld/mysqld.sock')
cur = conn.cursor(dictionary=True)
query = """SELECT column_name
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND table_name = 'Search'
"""
cur.execute(query)
fields = [x['column_name'] for x in cur.fetchall()]
user_input = ['maxPrice', 300, 10]
if user_input[0] in fields:
cur.execute("""UPDATE Search SET {0} = {1} WHERE id = {1}""".format(user_input[0], '%s'),
tuple(user_input[1:]))
print cur.statement
Prints:
UPDATE Search SET maxPrice = 300 WHERE id = 10
Where:
mysql> show create table Search\G
*************************** 1. row ***************************
Search
CREATE TABLE `Search` (
`id` int(11) DEFAULT NULL,
`maxPrice` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
A column name is not a parameter. Put the column name maxPrice directly into your SQL.
cursor.execute("""UPDATE Search SET maxPrice = %s WHERE searchID = %s""", (300, 10))
If you want to use the same code with different column names, you would have to modify the string itself.
sql = "UPDATE Search SET {} = %s WHERE searchID = %s".format('maxPrice')
cursor.execute(sql, (300,10))
But bear in mind that this is not safe from injection the way parameters are, so make sure your column name is not a user-input string or anything like that.
You cannot do it like that. You need to place the column name in the string before you call cursor.execute. Column names cannot be used when transforming variables in cursor.execute.
Something like this would work:
sql = "UPDATE Search SET {} = %s WHERE searchID = %s".format('maxPrice')
cursor.execute(sql, (300, 10,))
You cannot dynamically bind object (e.g., column) names, only values. If that's the logic you're trying to achieve, you'd have to resort to string manipulation/formatting (with all the risks of SQL-injection attacks that come with it). E.g.:
sql = """UPDATE Search SET {} = %s WHERE searchID = %s""".format('maxPrice')
cursor.execute(sql, (300, 10,))

(Python) cursor.execute(sql)

def makeProductTable():
"""This creates a database with a blank table."""
with connect("products.db") as db:
cursor = db.cursor()
cursor.execute("""
CREATE TABLE Product(
ProductID integer,
GTIN integer,
Description string,
StockLevel integer,
Primary Key(ProductID));""")
db.commit()
def editStockLevel():
with connect("products.db") as db:
cursor = db.cursor()
Product_ID=input("Please enter the id of the product you would like to change: ")
Stock_Update=input("Please enter the new stock level: ")
sql = "update product set StockLevel = ('Stock_Update') where ProductID = ('Product_ID');"
cursor.execute(sql)
db.commit()
return "Stock Level Updated."
The first function is used to make the table and it shows my column titles, the second function is needed to update a specific value in the table.
But when this is ran the inputs are executed, however when all show all the products in the table the value for stock level doesn't change.
So I think the problem has something to do with the cursor.execute(sql) line.
Or something like this?
cur.execute("UPDATE Product set StockLevel = ? where ProductID = ?",(Stock_Update,Product_ID))
Yes; you're passing literal strings, instead of the values returned from your input calls. You need to use parameters in the statement and pass thme to the execute call.
sql= "update product set StockLevel = %s where ProductID = %s;"
cursor.execute(sql, (Stock_Update, Product_ID))

How can I format strings to query with mysqldb in Python?

How do I do this correctly:
I want to do a query like this:
query = """SELECT * FROM sometable
order by %s %s
limit %s, %s;"""
conn = app_globals.pool.connection()
cur = conn.cursor()
cur.execute(query, (sortname, sortorder, limit1, limit2) )
results = cur.fetchall()
All works fine but the order by %s %s is not putting the strings in correctly. It is putting the two substitutions in with quotes around them.
So it ends up like:
ORDER BY 'somecol' 'DESC'
Which is wrong should be:
ORDER BY somecol DESC
Any help greatly appreciated!
paramstyle
Parameter placeholders can only be used to insert column values. They can not be used for other parts of SQL, such as table names, statements, etc.
%s placeholders inside query string are reserved for parameters. %s in 'order by %s %s' are not parameters. You should make query string in 2 steps:
query = """SELECT * FROM sometable order by %s %s limit %%s, %%s;"""
query = query % ('somecol', 'DESC')
conn = app_globals.pool.connection()
cur = conn.cursor()
cur.execute(query, (limit1, limit2) )
results = cur.fetchall()
DO NOT FORGET to filter first substitution to prevent SQL-injection possibilities
Not all parts of an SQL query can be parametrized. The DESC keyword for example is not
a parameter. Try
query = """SELECT * FROM sometable
order by %s """ + sortorder + """
limit %s, %s"""
cur.execute(query, (sortname, limit1, limit2) )
You could try this alternatively...
query = """SELECT * FROM sometable
order by {0} {1}
limit {2}, {3};"""
sortname = 'somecol'
sortorder = 'DESC'
limit1 = 'limit1'
limit2 = 'limit2'
print(query.format(sortname, sortorder, limit1, limit2))

Categories

Resources