I'm having a hard time getting some sql in python to correctly go through MySQLdb. It's pythons string formatting that is killing me.
My sql statement is using the LIKE keyword with wildcards. I've tried a number of different things in Python. The problem is once I get one of them working, there's a line of code in MySQLdb that burps on string format.
Attempt 1:
"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN
tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query)
This is a no go. I get value error:
ValueError: unsupported format character ''' (0x27) at index 128
Attempt 2:
"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN
tag ON user.id = tag.userId WHERE user.username LIKE '\%%s\%'" %
(query)
I get the same result from attempt 1.
Attempt 3:
like = "LIKE '%" + str(query) + "%'" totalq = "SELECT tag.userId,
count(user.id) as totalRows FROM user INNER JOIN tag ON user.id =
tag.userId WHERE user.username " + like
This correctly creates the totalq variable, but now when I go to run the query I get errors from MySQLdb:
File "build/bdist.macosx-10.6-universal/egg/MySQLdb/cursors.py", line
158, in execute query = query % db.literal(args) TypeError: not enough
arguments for format string
Attempt 4:
like = "LIKE '\%" + str(query) + "\%'" totalq = "SELECT tag.userId,
count(user.id) as totalRows FROM user INNER JOIN tag ON user.id =
tag.userId WHERE user.username " + like
This is the same output as attempt 3.
This all seems really strange. How can I use wildcards in sql statements with python?
Those queries all appear to be vulnerable to SQL injection attacks.
Try something like this instead:
curs.execute("""SELECT tag.userId, count(user.id) as totalRows
FROM user
INNER JOIN tag ON user.id = tag.userId
WHERE user.username LIKE %s""", ('%' + query + '%',))
Where there are two arguments being passed to execute().
It's not about string formatting but the problem is how queries should be executed according to db operations requirements in Python (PEP 249)
try something like this:
sql = "SELECT column FROM table WHERE col1=%s AND col2=%s"
params = (col1_value, col2_value)
cursor.execute(sql, params)
here are some examples for psycog2 where you have some explanations that should also be valid for mysql (mysqldb also follows PEP249 dba api guidance 2.0: here are examples for mysqldb)
To escape ampersands in Python string formatting expressions, double the ampersand:
'%%%s%%' % search_string
Edit: But I definitely agree with another answer. Direct string substitution in SQL queries is almost always a bad idea.
import mysql.connector
mydatabase = mysql.connector.connect(host="localhost", user="root", passwd="1234", database="databaseName")
mycursor = mydatabase.cursor()
user_input =[]
item = str("s%")
user_input.append(item)
mycursor.execute("SELECT * FROM employees WHERE FIRST_NAME LIKE %s ESCAPE ''",user_input )
result = mycursor.fetchall()
for row in enumerate(result):
print(row)
I used the following and it worked:
my_str = 'abc'
query = f"""select * from my_table where column_a like '%%{my_str}%%' """
df=pandas.read_sql_query(query, engine)
We could try escaping the percentage character by doubling them like this:
query_to_get_user_name = """
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag
ON user.id = tag.userId
WHERE user.username LIKE '%%%s%%' """ % (user_name,)
cursor.execute(query_to_get_user_name)
So I tried this and I think I have got the answer which is simpler for me to understand , a school student .
In my code the table name is "books" and the column I'm Searching for is "Name".
If you need more xplaination , then feel free to drop a mail at dhruv2003.joshi#gmail.com and I will try my best to answer ASAP
def S():
n=str(input('Enter the name of the book: '))
name='%'+n+'%'
NAME=name
query="select * from books where Name like '"+NAME+"' "
c.execute(query)
ans=c.fetchall()
if len(ans)>0:
print('')
for i in ans:
print(i)
print('')
else:
print('')
print('An error occured')
print('Name you gave does not exist :( ')
print('')
I have a solution to your problem :
You can not use :
"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query)
you can change it with string template, such as :
import MySQLdb
import string # string module
.......
value = {'user':'your value'}
sql_template = string.Template("""
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN
tag ON user.id = tag.userId WHERE user.username LIKE '%$user%'
""")
sql = sql_template.substitute(value)
try:
cursor.execute(sql)
...........
except:
...........
finally :
db.close()
Related
I am trying different ways to work out on Wildcard in Python for my SQL Query, Could anyone please help me in my syntax:
I need Query like ,
SELECT Title from Task where Title like '%abc%' -- SQL
to be written in Python
TRY 1:
sql = '''
(""" SELECT TITLE FROM TASK
WHERE TITLE LIKE %s""", ('%' +?+ '%',))
'''
cursor.execute(sql, id)
data = cursor.fetchone()
TRY 2:
sql = '''
(""" SELECT TITLE FROM TASK
WHERE TITLE LIKE '%%%?%%'
'''
cursor.execute(sql, id)
data = cursor.fetchone()
ANy help on my syntax please.
I think something like this should work
sql = '''
(""" SELECT TITLE FROM TASK
WHERE TITLE LIKE '{}'
'''
sql.format(id)
cursor.execute(sql)
data = cursor.fetchone()
Here is a simple solution:
wildcard = 'example'
sql = f"""
SELECT TITLE FROM TASK
WHERE TITLE LIKE '{wildcard}'
"""
cursor.execute(sql)
data = cursor.fetchone()
This should simply replace the {wildcard} with whatever you decide in the wildcard = "?" part.
You can parse it like this :
wildcar_str = '%abc%'
sql = "SELECT TITLE FROM TASK WHERE TITLE LIKE '%s' " %wildcar_str
I try to get the number of movies that include the word "the" in their title, by LIKE clause. in Python connectors MySQL:
word='the'
query = """ SELECT COUNT(title) from movies WHERE title LIKE '%%%s%%' """ % (word,)
cursor.execute(query)
# error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT COUNT(title) from movies WHERE title LIKE '%the%'' at line 1
p = "the"
query = ("SELECT COUNT(title) from movies WHERE title LIKE", ("%" + p + "%",))
cursor.execute(query,(p,))
# AttributeError: 'tuple' object has no attribute 'encode'
You would do:
query = "SELECT COUNT(title) from movies WHERE title LIKE CONCAT('%', %s, '%')";
cursor.execute(query, (word,))
This uses a proper prepared statement to pass the variables to the query, so the code is safe from SQL injection, and more efficient.
You could also do the concatenation of wildcard on application side:
query = "SELECT COUNT(title) from movies WHERE title LIKE %s";
cursor.execute(query, ('%' + word + '%',))
I need a way to fetch similar records from DB using LIKE from Django .
My code is :
def fetchProductsDate1(request):
query = request.session.get('query')
date1 = request.session.get('date1')
db = pymysql.connect(host=host,user=user,passwd=passwd,db=dbName)
# Create a Cursor object to execute queries.
cur = db.cursor()
# Select data from table using SQL query.
stmt = "SELECT FSN FROM tab WHERE query LIKE '%s' AND DATE(updated_at) LIKE '%s' " % (query.replace("'", r"\'"), date1)
log.info(stmt)
cur.execute(stmt)
rows = cur.fetchall()
json_data = rows[0][0]
The db statement looks like:
SELECT num FROM tab WHERE query LIKE 'soch sarees' AND DATE(updated_at) LIKE '2018-11-14'
I want the statement to be like :
SELECT num FROM tab WHERE query LIKE '%soch sarees%' AND DATE(updated_at) LIKE '2018-11-14'
Any help will be really nice :)
Thanks.
You can use %% to do that
stmt = "SELECT FSN FROM tab WHERE query LIKE '%%%s%%' AND DATE(updated_at) LIKE '%s' " % (query.replace("'", r"\'"), date1)
Which will give us
SELECT FSN FROM tab WHERE query LIKE '%soch sarees%' AND DATE(updated_at) LIKE '2018-11-14'
Also, I think it' a bad practice to concat parameters like this.This opens path to SQL Injection
You could try:
select_stmt = "SELECT FSN FROM tab WHERE query LIKE '%%%(name)%%%' AND DATE(updated_at) LIKE '%(date)%'"
cursor.execute(select_stmt, { 'name': 'soch sarees','date':'2018-11-14' })
I want to fetch all rows from MySQL table with
query = "SELECT * FROM %s WHERE last_name=%s"
cursor.execute(query, ("employees","Smith"))
but I'm getting
You have an error in your SQL syntax. When I try
query = "SELECT * FROM employees WHERE last_name=%s"
cursor.execute(query, ("Smith",))
all is fine.
Documentation says
cursor.execute(operation, params=None, multi=False)
The parameters found in the tuple or dictionary params are bound to the variables in the operation.link on docs
The first will generate an SQL like this:
SELECT * FROM 'employees' WHERE last_name='smith'
The parameters are SQL quoted.
If you really need to have a table name as param, you must proceed in 2 steps:
table_name = 'employees'
query_tpl = "SELECT * FROM {} WHERE last_name=%s"
query = query_tpl.format(table_name)
cursor.execute(query, ("Smith",))
you need to add the quote symbol. So the query will be like
SELECT * FROM employees WHERE last_name='Smith'
Change both your query to
query = "SELECT * FROM %s WHERE last_name='%s'"
query = "SELECT * FROM employees WHERE last_name='%s'"
You can't use a parameter for the table name in the execute call.
But you can use Python string interpolation for that:
query = "SELECT * FROM %s WHERE last_name=%s" %("employees","Smith")
cursor.execute(query)
You can't use a table name as a parameter. you are generating invalid sql with your code that is putting quotes around each string. the table name cannot have quotes around it.
sql you are generating
select * from 'employees' where last_name = 'Smith'
What sql you want
select * from employees where last_name = 'Smith'
you would have to format the string first like the example below.
query = "SELECT * from {} wherre last_name ='{}'"
cursor.execute(query.format("employees","Smith"))
using code like this does open up the possibility of SQL injection. so please bear that in mind.
query="SELECT * FROM %s WHERE name=%s",(employees,smith)
cursor.execute(query)
rows = cursor.fetchall()
Try this one. Hopefully it works for you.
Using Python's mysql.connector, how can I select all records that match a tuple?
For example:
ids = (b'6TRsHMzWSrq0zeembo0Vbg',
b'7Qoq53lKTk-RZOi830t3MA',
b'7ZGO9S3DTcGHjwrfpV0E0A')
And then the query would do something like:
query = SELECT first_name
FROM users
WHERE id = (ids)
Returning records for all users whose ID appears in the tuple
Try doing this
query = "SELECT first_name FROM users WHERE id IN " + str(list(ids))
cursor.execute(query)
On second thoughts, the following should also work
query = "SELECT first_name FROM users WHERE id IN " + str(ids)
EDIT
OP mentions in comments that the ids are binary data returned from a previous query. In which case, taking hint from this answer and using BINARY operator, the following query should work
query = "SELECT first_name FROM users WHERE BINARY id IN " + str(ids) ;