As it is said in asyncpg Usage, I can use $n pattern for the arguments and execute a query this way, for example:
result = await conn.fetchval("SELECT $1", 42)
In this case the raw SQL would be SELECT 42. How do I get this raw text with an asyncpg function before execution? I am asking this is because I want to log queries in my project before they are applied.
query_tpl = "SELECT $1"
values = (42,)
sql = what_is_here(query_tpl, *values) # <- ???
print(sql) # Must be "SELECT 42"
result = await conn.fetchval(query_tpl, *values)
Related
I use this code:
I want to place the value in the SQL command via the% s operator, but when I reference the change value with% s, the command does not work:
s='amiravira.ir'
q1 = "SELECT DISTINCT name_cat FROM all_user WHERE id='%s' "
mycursor = mydb.cursor()
mycursor.execute( q1 ,s)
myresult = mycursor.fetchall()
myresult
The value can be found only if I write the SQL command line itself.
This is exactly the end of my project and it's really weird. I do not know why this happens:
q1 = "SELECT DISTINCT name_cat FROM all_user WHERE id = 'amiravira.ir'"
mycursor = mydb.cursor ()
mycursor.execute (q1, s)
myresult = mycursor.fetchall ()
myresult
I want to know what should I do to send data via SQL statements?
The argument(s) for the execute-call must be passed as an iterable (tuple or list), even if there's only one.
So write instead:
mycursor.execute(q1, (s,))
to pass the argument as an one element tuple.
hi i am looking to insert these 3 values into my SQL database table that has columns: email, cardnumber, dateandtime
here is my code:
email = input("Email: ")
cardnumber = int(input("Enter card number:"))
now = datetime.now()
now = now.strftime('%Y-%m-%d %H:%M:%S')
newrowforsql()
my code for the query is:
def newrowforsql():
query = """\
insert into table1 (email,cardnumber,dateandtime)
values(email,cardnumber,now)"""
insertnewrow = execute_query_commit(conn, query)
I cant seem to insert the values
my code for executing the query and committing it is:
def execute_query_commit(connection, query):
cursor = connection.cursor()
try:
cursor.execute(query)
connection.commit()
print("Query executed and committed")
except pyodbc.Error as e:
print(f"The error '{e}' occurred")
As "azro" mentioned correctly you didn't put in the variable content to the query, you just put in the name of the variable which contains the information you want. What you need to change is the following:
def newrowforsql():
query = """\
insert into table1 (email,cardnumber,dateandtime)
values(email,cardnumber,now)"""
insertnewrow = execute_query_commit(conn, query)
to
def newrowforsql():
query = """\
insert into table1 (email,cardnumber,dateandtime)
values({theEmail},{theCardnumber},{now})""".format(theEmail=email, theCardnumber=cardnumber, now=now)
insertnewrow = execute_query_commit(conn, query)
This is one of the most used options to manipulate strings in python. But if you are using python3.7+ (maybe from Python3.6 and up, but I'm not sure) there is a much better and faster option to manipulate strings, it's name is "f-strings".
Here is the same solution but with f-strings instead of the method str.format
def newrowforsql():
query = f"""\
insert into table1 (email,cardnumber,dateandtime)
values({email},{cardnumber},{now})"""
insertnewrow = execute_query_commit(conn, query)
Good luck!
I'm learning programming with python and trying to implement the safest possible MySQL queries starting with the simple SELECT ones. The problem is whenever I use coma in a query I got the following error:
cursor.execute(query)
File "C:\Users\username\AppData\Local\Programs\Python\Python37-32\lib\site-packages\mysql\connector\cursor.py", line 536, in execute
stmt = operation.encode(self._connection.python_charset)
AttributeError: 'tuple' object has no attribute 'encode'
I am aware of the fact that coma itself isn't a source of a problem but I tried many different MySQL syntax and everytime I use a come I got this "AttributeError: 'tuple' object has no attribute 'encode'" error.
I also tried to change MySQL database encoding - nothing changes. The code is below.
import mysql.connector
conn = mysql.connector.connect(
charset='utf8',
# init_command='SET NAMES UTF8',
host="10.0.0.234",
user="x",
passwd="x>",
database="x",
)
print(conn.is_connected())
param = "test"
cursor = conn.cursor()
# =========== query below does work ========
# query = ("SELECT * from list WHERE username LIKE '%test%'")
# ============ query below does work =======
# query = ("SELECT * from list HAVING username = '%s'" % param)
# ============ query below doesn't work =====
# query = ("SELECT * from list HAVING username = %s", (param,))
# ============= query below doesn't work =====
query = "SELECT * from list WHERE username = :name", {'name': param}
cursor.execute(query)
result = cursor.fetchall()
for x in result:
print(x)
conn.close()
Any ideas what am I doing wrong?
The answer is a little bit tricky, but it is in essence because of what the actual value of the 'query' variable is...
For example:
# 1.
query = ("SELECT * from list WHERE username LIKE '%test%'")
# when you do this, query is a string variable,
# NB: the parentheses are not necessary here
# so when you call
cursor.execute(query)
# the value passed into the execute call is the string "SELECT * from list WHERE username LIKE '%test%'"
# 2.
query = ("SELECT * from list HAVING username = '%s'" % param)
# when you do this, query is the result of a string formatting operation
# This is a Python 2 form of string formatting
# The discussion here probably makes it more clear:
# https://stackoverflow.com/questions/13945749/string-formatting-in-python-3
# it is almost the same as doing this:
query = "SELECT * from list HAVING username = 'test'"
# so when you call
cursor.execute(query)
# the value passed into the execute call is the string "SELECT * from list HAVING username = 'test'"
# 3.
query = ("SELECT * from list HAVING username = %s", (param,))
# This operation is assigning a 2-value tuple into the query variable
# The first value in the tuple is the string "SELECT * from list HAVING username = %s"
# The second value in the tuple is a 1-value, with 'test' as its first value
# 4.
query = "SELECT * from list WHERE username = :name", {'name': param}
# This is similar to #3, but the values in the tuple are instead
# query[0] == "SELECT * from list WHERE username = :name"
# query[1] is a dictionary: {'name': param}
Both 3 and 4 above are not calling the MySQL execute with the parameters you are expecting (see API here). You probably need to do one of:
unpack the query tuple into separate variables, and call the function with them
operation, params = query # unpack the first elem into operation, and second into params
cursor.execute(operation, params)
just index into the query tuple
cursor.execute(query[0], query[1])
# NB: you could also use the 'named parameters' feature in Python
cursor.execute(query[0], params=query[1])
Use the 'unpacking arguments list' (SPLAT operator)
cursor.execute(*query)
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've build a simple Python API which receives JSON dictionaries with strings and numeric values from the clients.
In order to protect my system and avoid MySQL-Injections I escape the strings when I'm using it f.ex.:
jsonInput = request.get_json(force=True, silent=True) # INPUT FROM HTTP POST REQUEST
# ESCAPING STRING BY STRING
flowerColor = MySQLdb.escape_string(jsonInput['flowerColor'])
flowerSize = MySQLdb.escape_string(jsonInput['flowerSize'])
query = "SELECT * FROM flowers WHERE color='" + flowerColor + "' AND size='" + flowerSize + "'"
try:
conn = // CONNECT TO DB
cursor = conn.cursor()
cursor.execute(query)
return cursor.fetchall()
except MySQLdb.IntegrityError:
return False
In my opinion it would be way easier, if there is a method to just escape the whole input at once, so every string in the JSON can be used directly after the escape method in a MySQL query. For example:
jsonInput = request.get_json(force=True, silent=True) # INPUT FROM HTTP POST REQUEST
# ESCAPING WHOLE JSON AT ONCE
escapedJSON = escape_json_at_once(jsonInput)
query = "SELECT * FROM flowers WHERE color='" + escapedJSON['flowerColor'] + "' AND size='" + escapedJSON['flowerSize'] + "'"
try:
// EXECUTE THE QUERY
except MySQLdb.IntegrityError:
return False
// DO OTHER QUERIES WITH ESCAPED JSON DATA
I already found the method MySQLdb.escape_dict() but couldn't get it to work also with reading the docs.
Does somebody know a way to escape the whole input at once?
yes, there is indeed a better way
jsonInput = request.get_json(force=True, silent=True) # INPUT FROM HTTP POST REQUEST
query = "SELECT * FROM flowers WHERE color=%s AND size=%s"
try:
conn = // CONNECT TO DB
cursor = conn.cursor()
cursor.execute(query, ( jsonInput['flowerColor'],jsonInput['flowerSize']) )
return cursor.fetchall()
except MySQLdb.IntegrityError:
return False
With this approach you don't need to escape anything at all and it's shorter and neater.