This question already has an answer here:
How do I escape % from python mysql query
(1 answer)
Closed 6 years ago.
I use PyMySQL to query from a MySQL database in python:
filter = "Pe"
connection = pymysql.connect(host="X", user="X", password="X", db="X", port=3306, cursorclass=pymysql.cursors.SSCursor)
cursor = connection.cursor()
sqlquery = "SELECT * FROM usertable WHERE name LIKE '%%s%'"
cursor.execute(sql, (filter))
response = cursor.fetchall()
connection.close()
This returns nothing.
I could write:
sqlquery = "SELECT * FROM usertable WHERE name LIKE '%" + filter +"%'"
and execute: cursor.execute(sql), but then I lose the escaping, which makes the program vulnerable for injection attacks, right?
Is there way I could insert the value into the LIKE without losing the escape?
...WHERE name LIKE '%%%s%%'" does not work. I think %s adds ' on both sides of the replaced escaped string as a part of its function within PyMySQL.
You need to pass the whole pattern as a query parameter, and use a tuple:
filter = "%Pe%"
sql = "SELECT * FROM usertable WHERE name LIKE %s"
cursor.execute(sql, (filter,))
Double the % you want to keep.
sqlquery = "SELECT * FROM usertable WHERE name LIKE '%%%s%%'"
Related
I have a following sql query:
SELECT *
FROM %s.tableA
The tableA is in db-jablonec so I need to call db-jablonec.tableA.
I use this method in Python:
def my_method(self, expedice):
self.cursor = self.connection.cursor()
query = """
SELECT *
FROM %s.tableA
"""
self.cursor.execute(query, [expedice])
df = pd.DataFrame(self.cursor.fetchall())
I call it like this:
expedice = ["db-jablonec"]
for exp in expedice:
df = db.my_method(exp)
But I got an error MySQLdb.ProgrammingError: (1146, "Table ''db-jablonec'.tableA' doesn't exist")
Obviously, I want to call 'db-jablonec.tableA' not ''db-jablonec'.tableA'. How can I fix it please?
It is passing %s as its own string including the quotes ''
you therefore need to pass it as one variable. Concatenate .table to the variable itself then pass it in.
Your query will therefore then be
query = """
SELECT *
FROM %s
"""
I think this will helpful for you
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%%'
Refer This.
I've a script that makes a query to my database on MySQL. And my doubt is if I can pass any parameter to that query through Python.
For example, on the following script I want to calculate the date_filter using Python and then apply that filter on the query.
now = dt.datetime.now()
date_filter = now - timedelta(days=3)
dq_connection = mysql.connector.connect(user='user', password='pass', host='localhost', database='db')
engine = create_engine('localhost/db')
cursor = connection.cursor(buffered=True)
query = ('''
SELECT *
FROM myTable
WHERE date >= ''' + date_filter + '''
''')
I try it on that way but I got the following error:
builtins.TypeError: can only concatenate str (not "datetime.datetime") to str
It is possible to apply the filter like that?
Thanks!
Yes, you can do it. To avoid sql injections, the best way is not using the python formatting facilities, but the sql parameters & placeholders (see that you donĀ“t need the single quotes ' as the placeholder does the job and converts the type of the variable):
now = dt.datetime.now()
date_filter = now - timedelta(days=3)
dq_connection = mysql.connector.connect(user='user', password='pass', host='localhost', database='db')
engine = create_engine('localhost/db')
cursor = db_connection.cursor(buffered=True)
query = "SELECT * FROM myTable WHERE date >=%s"
cursor.execute(query,(date_filter,))
Also, you had a mistake in your cursor, it should be db_connection.cursor. The last comma after date_filter is ok because you need to send a tuple.
In case you need more than one paremeter, you can place more than one placeholder:
query = "SELECT * FROM myTable WHERE date >=%s and date<=%s"
cursor.execute(query,(date_filter,other_date))
You can just do something like:
WHERE date >= ''' + str(date_filter) + '''
to represent the date as string as not a datetime object.
You can try with this:
date_f = str(date_filter)
query = ('''
SELECT *
FROM myTable
WHERE date >= "{}"
'''.format(date_f))
I need to query data from a mysqldatabase with the table name containing hyphens.
current_table = "tw3-10_1"
sql2 = "SELECT * FROM " + str(current_table )
cursor.execute(sql2)
Unfortunately I get:
1064, "You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-10_1' at line 1")
Is there any way to work around that issue? Unfortunately I cannot change the names of the tables.....
You can normally use backticks to quote a table name or column name, in case it contains unhelpful characters.
current_table = "`tw3-10_1`"
sql2 = "SELECT * FROM " + current_table
or if you prefer
current_table = "tw3-10_1"
sql2 = "SELECT * FROM `{}`".format(current_table)
try like this, I don't know about MariaDB but quotes should work in SQL
sql2 = """
SELECT
*
FROM "{table_name}"
""".format(
table_name='table-with-hyphens'
)
print(sql2)
# SELECT
# *
# FROM "table-with-hyphens"
I have a problem with my python code which I want to use for a REST API server.
The current problem is that my database query is returning null when I know that the value is there
The code for the specific path:
#app.route('/data/active_predicted/<int:ticketId>', methods=['GET'])
def search_db_tickId_act(ticketId):
cursor = db.cursor()
db_query = cursor.execute("select * from active_predicted where ticketId=" + str(ticketId))
json_output = json.dumps(dict(cursor.fetchall()))
cursor.close()
if not cursor.fetchall():
return "Nothing found \n SQL Query: " + "select * from active_predicted where ticketId=" + str(ticketId)
else:
return str(cursor.fetchall())
When I access this URL I get returned the following:
Nothing found SQL Query: select * from active_predicted where ticketId=1324
When I plug this SQL query I get the result I want, 1 row with 2 columns but it seems as though the program cannot locate the row?
The problems:
As #pvg mentioned, you need to escape your input values when querying database;
If you want to fetch a dictionary-like result, passing dictionary=True when you initialize the cursor;
In your original code, you didn't return the variable json_output;
To fetch only one result, use fetchone instead fetchall;
After cursor.close() got called, you can obtain nothing from that cursor no matter you fetched before or not;
Use try-finally to ensure that cursor always get closed (at last).
Here's the fixed code:
#app.route('/data/active_predicted/<int:ticketId>', methods=['GET'])
def search_db_tickId_act(ticketId):
try:
cursor = db.cursor(dictionary=True)
db_query = cursor.execute("select * from active_predicted where ticketId=%s LIMIT 1", ticketId)
row = cursor.fetchone()
if row:
return json.dumps(row)
else:
return "Nothing found \n SQL Query: " + "select * from active_predicted where ticketId=" + str(ticketId)
finally:
cursor.close()
I get the error when running this code:
import sqlite3
user_name = raw_input("Please enter the name: ")
user_email = raw_input("Please enter the email: ")
db = sqlite3.connect("customer")
cursor=db.cursor()
sql = """INSERT INTO customer
(name, email) VALUES (?,?);,
(user_name, user_email)"""
cursor.execute(sql)
Why is this happening?
While the other posters are correct about your statement formatting you are receiving this particular error because you are attempting to perform multiple statements in one query (notice the ; in your query which separates statements).
From Python sqlite3 docs:
"execute() will only execute a single SQL statement. If you try to execute more than one
statement with it, it will raise a Warning. Use executescript() if you want to execute
multiple SQL statements with one call."
https://docs.python.org/2/library/sqlite3.html
Now your statement will not execute properly even if you use executescript() because there are other issues with the way it is formatted (see other posted answers). But the error you are receiving is specifically because of your multiple statements. I am posting this answer for others that may have wandered here after searching for that error.
Use executescript instead of execute
execute() will only execute a single SQL statement. If you try to execute more than one statement with it, it will raise a Warning. Use executescript() if you want to execute multiple SQL statements with one call.
https://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.execute
You have a ;, in the middle of the query string - that is an invalid syntax. Pass a dictionary as a second argument to execute if you want to use a named parameter binding.
sql = "INSERT INTO customer (name, email) VALUES (:name, :email)"
cursor.execute(sql, {'name':user_name, 'email':user_email})
Try this:
sql = """INSERT INTO customer
(name, email) VALUES (?,?)"""
cursor.execute(sql, (user_name, user_email))
import sqlite3
def DB():
List = {"Name":"Omar", "Age":"33"}
columns = ', '.join("" + str(x).replace('/', '_') + "" for x in List.keys())
values = ', '.join("'" + str(x).replace('/', '_') + "'" for x in List.values())
sql_qry = "INSERT INTO %s ( %s ) values (?,?) ; ( %s )" % ('Table Name', columns, values)
conn = sqlite3.connect("DBname.db")
curr = conn.cursor()
# curr.execute("""create table if not exists TestTable(
# Name text,
# Age text
# )""")
# print columns
# print values
# print sql
# sql = 'INSERT INTO yell (Name , Age) values (%s, %s)'
curr.execute(sql_qry)
DB()