Python - SQL Connector: Update do not work - python

I want to update records in MySQL. However, I always get an error that the syntax does not work. I think it is a formatting error, however I can't manage to fix it.
Error message:
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 ''ovd' = 1 WHERE id = '16923'' at line 1
My code looks like:
func = ['OffizierIn vom Dienst Bezirk', 'EinsatzoffizierIn']
dbFields = ["ovd", "offizier"]
x = 0
for i in func:
el = chrome.find_element_by_id('RoleId')
for option in el.find_elements_by_tag_name('option'):
if option.text == i:
option.click()
chrome.find_element_by_id('SearchBtn').submit()
time.sleep(2)
tbody = chrome.find_element_by_id('SearchResults')
for row in tbody.find_elements_by_xpath('./tr'):
itemsEmployee = row.find_elements_by_xpath('./td')
cursor.execute('UPDATE employees SET %s = 1 WHERE id = %s;', (dbFields[x], itemsEmployee[1].text))
x = x + 1
In the first pass, the values are as in the error message: dbFields[x] = ovd itemsEmplyee[1] = 16923
The table was created as follows:
cursor.execute('CREATE TABLE IF NOT EXISTS employees (id INT NOT NULL UNIQUE, ovd BOOLEAN);')

You've encountered one of the annoyances in writing dynamic database queries: values must be quoted, if necessary, with quotation marks, as performed by the connector package, but table and column names, if quoted, are quoted with backticks. See the MySQL rules.
You need to add the column name using string formatting, then pass the value to a prepared statement:
stmt = f'UPDATE employees SET `{dbFields[x]}` = 1 WHERE id = %s;'
cursor.execute(stmt, (itemsEmployee[1].text,))

Related

Python MySQL, 1064 (42000), "You have an error in your SQL syntax;..."

This's my table test_table:
id name
1 aa
2 bb
3 cc
I get the message when it’s run with python3:
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 'test as(SELECT * from test_table) SELECT name FROM test' at line 1
this is my syntax:
cnxn = mysql.connector.connect(**sql_config)
cursor = cnxn.cursor()
query = """
with test as(SELECT * FROM `test_table`)
SELECT * FROM test
"""
cursor.execute(query)
get_data = cursor.fetchall()
cnxn.close()
cursor.close()
The bug may be in syntax of query.
Because I tried the following two methods with without error:
1.Sequel Ace: use 'with'
with `test` as ( SELECT * FROM `test_table`)
SELECT `name` FROM `test`
2.python3: not used ‘with’ and can work
query = """
SELECT name FROM test_table
"""
How do I modify 'with as' of syntax?
query = """
with test as(SELECT * FROM test_table)
SELECT * FROM test
"""
I'm almost sure you're on an old version of mysql. The Common table expression feature (that one with "with") was introduce only in version 8.
Every version below 8 will return you exact same error message. See first db_fiddle
Whereas the same query runs perfect starting from version 8 as you may seen on the second db_fiddle example
But that's not the end. The CTE can be replaced with a subquery like this
SELECT name FROM (select 'XXX' name) q;
or, in case, if you need to join:
select x.name
FROM (select 'XXX' name) x
JOIN (select 'XXX' name union all select 'YYY') y
ON x.name = y.name;
as you can see on third db_fiddle example

Trying to update the mysql table with user friendly input using string formatting

Though it is a repeated question , but want to know where my code is wrong as I am facing a syntax error .
def update_block():
table_name = input("Enter the name of the table: ")
column_update = input("Enter the column name to be updated: ")
column_name = input("Enter the column where the operation is to be performed: ")
name = input("Enter the name has to get update: ")
column_value = input("Enter the column value: ")
try:
sql_update_query = f"""Update {table_name} set {column_update} = %s where {column_name} = %s"""
inputData = (f"{name},{column_value}" )
my_cursor.execute(sql_update_query,inputData)
mydb.commit()
print("Record Updated successfully ")
except mysql.connector.Error as error:
print("Failed to update record to database: {}".format(error))
finally:
if (mydb.is_connected()):
my_cursor.close()
mydb.close()
print("MySQL connection is closed")
update_block()
error i am getting as :
Failed to update record to database: 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 '%s where prj_id = %s' at line 1
MySQL connection is closed
f"""Update {table_name} set {column_update} = %s where {column_name} = %s"""
You used f strings with curly brackets and %s notation here. Do either one and it should work
e.g.:
f"""Update {table_name} set {column_update} = {name} where {column_name} = {column_value}"""
There are two problems with the code.
In this line,
sql_update_query = f"""Update {table_name} set {column_update} = %s where {column_name} = %s"""
the table and column names should be quoted with backticks ("`") to handle names containing spaces or hyphens (or some unicode characters). So the line would look like this.
sql_update_query = f"""Update `{table_name}` set `{column_update}` = %s where `{column_name}` = %s"""
Note that the placeholders for variables should remain as %s.
In this line
inputData = (f"{name},{column_value}" )
the variables' values are being converted to strings within a single string. But the statement expects two variables, not one. Also, it is better* to pass the raw variables to the database connection and let the connection manage formatting them correctly in the final query. So the line should be
inputData = (name, column_value)
And now the statement can be executed with the related variables
my_cursor.execute(sql_update_query, inputData)
* The driver knows how to correctly convert Python data types into those expected by the database, and how to escape and quote these values. This provides at least two benefits:
it helps prevent SQL injection attacks, where a malicious user provides an SQL statement as a variable value (such as "; DELETE FROM mytable;"
it ensures that values are processed as expected; consider this statement:
SELECT '2020-09-01' AS `Quoted Date`, 2020-09-01 AS `Unquoted Date`;
+-------------+---------------+
| Quoted Date | Unquoted Date |
+-------------+---------------+
| 2020-09-01 | 2010 |
+-------------+---------------+

Psycopg2 query remove \n from args

Im using python3 and postgres 11.5.
This is the script :
a = cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
for table in a:
cursor.execute("SELECT * FROM pg_prewarm(public.%s)", [table[0]])
a query gets some table names , and the loop query should run table name as the %s.
but for some reason i get the arg table[0] with // /n in the query and its messing it up.
if i print a results i get table names as tuple:
[('sa1591354519',), ('sa1591397719',), ('sa1591397719',)]
so [table[0]] is a string.
the error i get:
1574683839 [16177], ERR, execute ({'Error while connecting to PostgreSQL': SyntaxError('syntax error at or near "\'sa1591440919\'"\nLINE 1: SELECT * FROM pg_prewarm(public.\'sa1591440919\')\n ^\n')},)
what can i do ?
The errors don't have anything to do with the newlines you see, which are just an artifact of the error message. If you were to print out the error, would see:
syntax error at or near "'sa1591440919'"
LINE 1: SELECT * FROM pg_prewarm(public.'sa1591440919')
^
In other words, Postgres doesn't like the table name you're passing because it contains quotes. This is happening because you're trying to treat the table names like a normal query parameter, which causes psycopg to quote them...but that's not what you want in this case.
Just replace your use of query templating with normal Python string substitution:
a = cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
for table in a:
cursor.execute("SELECT * FROM pg_prewarm(public.%s)" % (table[0]))
But this won't actually work, because cursor.execute doesn't return a value, so a will be None. You would need to do something like:
cursor.execute("SELECT tablename FROM pg_catalog.pg_tables limit 5")
a = cursor.fetchall()
for table in a:
...

How to update a column in MySQL

I want to update a column in table in MySQL with some information that I retrieved from a website.The name of this column is "names" and the name of the table is "HuntsPointYelp"
I am getting ProgrammingError for my UPDATE query, which I think it is a syntax error.
Thanks!
import pymysql
conn = pymysql.connect(host='127.0.0.1',
unix_socket='/tmp/mysql.sock',user='root',
passwd=' ', db='mysql', charset='utf8')
cur = conn.cursor()
cur.execute('USE HuntsPointsBusinesses')
def storeNames (names):
cur.execute('UPDATE HuntsPointYelp SET = ("%s")', names)
cur.connection.commit()
def getNames (bs):
#names:
restGrid = bs.find_all ("ul", {"class": "lemon--ul__373c0__1_cxs
undefined list__373c0__2G8oH"})
#namesList = []
time.sleep(2)
for i in restGrid:
h3 = i.find_all ("h3")
for h in h3:
target = h.find_all ("a")
for t in target:
if "name" in t.attrs:
if t.attrs is not None:
names = t["name"]
storeNames (names)
driver.get ("https://www.yelp.com/search?
cflt=restaurants&find_loc=Hunts+Point%2C+Bronx%2C+NY+10474")
pageSource = driver.page_source
bs = BeautifulSoup (pageSource, "html.parser")
names = getNames(bs)
ProgrammingError: (1064, '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 \'= ("\'Roaming Woodfired Pizza\'")\'
at line 1')
You have two problems.
First, you're missing the name of the column to set. Second, you shouldn't put the placeholder in quotes; cur.execute() does the necessary quoting for you, so you end up with literal quotes in the value.
cur.execute('UPDATE HuntsPointYelp SET names = %s', names)

Dynamic query in django with "|" character in WHERE clause and variable in tablename

I have a dynamic sql query running in my views.py and have already ran others that work fine. I am not worried about sql injections because this is a private website. However, the parameters in my And clause has the character "|" in it which throws the error:
Unknown column "X" in 'where clause'
I have looked at solutions but they all use non dynamic query which then prohibits me from making the tablename a variable.
Here is what I want:
mycursor = mydb.cursor()
assembly_name = "peptides_proteins_000005"
group_id = 5
protein_id = "sp|P48740|MASP1_HUMAN"
qry = "SELECT * FROM %s WHERE group_id = %i AND protein_id = %s" % (assembly_name, group_id, protein_id)
mycursor.execute(qry)
But this throws the error:
mysql.connector.errors.ProgrammingError: 1054 (42S22): Unknown column 'sp' in 'where clause'
When I try doing following the answers of similar questions I get this:
qry = "SELECT * FROM %s WHERE group_id = %i AND protein_id = %s"
mycursor.exectue(qry, (assembly_name, group_id, protein_id))
However, I still get this error:
mysql.connector.errors.ProgrammingError: Not all parameters were used in the SQL statement
Changing the %i to a %s fixes the error above but then I get a new 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 ''peptides_proteins_000005' WHERE group_id = 5 AND protein_id = 'sp|P48740|MASP1_' at line 1
And here is where the loop ends, because looking up this error online suggests to write something similar to the query at the top. Can anybody help me figure out a way to do this?
For me, there was not way to do this, so I had to put literal quotes around the %s.
My final code looked something like this:
assembly_name = peptide_protein_formatter(assembly_name)
mycursor = mydb.cursor()
qry = "SELECT peptide_id,search_id FROM %s WHERE group_id = %s AND protein_id = '%s'" % (assembly_name, group_id, protein_id)
mycursor.execute(qry)
result = mycursor.fetchall()

Categories