My variable values are derived from the edited grid cell. The function works but the edited field name is named "Read". I fixed it by changing the column name, but I am curious why that is an error and if there are any other field name titles I should avoid.
Message=(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 'Read = 'ALL' where User_ID = 'j_adams58'' at line 1")
Table fields
| User_ID | Password | Read | Edit |
def onCellChanged(self,event):
#Establish connection
self.connect_mysql()
#Update database
key_id = str(self.GetCellValue(event.GetRow(),1))
target_col = str(self.GetColLabelValue(event.GetCol()))
key_col = str(self.GetColLabelValue(1))
nVal = self.GetCellValue(event.GetRow(),event.GetCol())
sql_update = f"""Update {tbl} set {target_col} = %s where {key_col} = %s"""
row_data = ''
self.cursor.execute(sql_update, (nVal, key_id,))
#Close connection
self.close_connection()
Read is a reserved keyword in MySQL, so you shouldn't use it as a column name, but if you really need to, you should be able to access it by putting single backticks around it, like `Read`, but again, it's really bad style and you shouldn't do it. You should also avoid using other keywords, but it's usually best to try the queries you'll run in SQL first so you can check if you can.
See: https://dev.mysql.com/doc/refman/8.0/en/keywords.html#keywords-8-0-detailed-R
Related
fairly new to SQL in general. I'm currently trying to bolster my general understanding of how to pass commands via cursor.execute(). I'm currently trying to grab a column from a table and rename it to something different.
import mysql.connector
user = 'root'
pw = 'test!*'
host = 'localhost'
db = 'test1'
conn = mysql.connector.connect(user=user, password=pw, host=host, database=db)
cursor = conn.cursor(prepared=True)
new_name = 'Company Name'
query = f'SELECT company_name AS {new_name} from company_directory'
cursor.execute(query)
fetch = cursor.fetchall()
I've also tried it like this:
query = 'SELECT company_name AS %s from company_directory'
cursor.execute(query, ('Company Name'),)
fetch = cursor.fetchall()
but that returns the following error:
stmt = self._cmysql.stmt_prepare(statement)
_mysql_connector.MySQLInterfaceError: 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 '? from company_directory' at line 1
I'm using python and mySQL. I keep reading about database injection and not using string concatenation but every time I try to use %s I get an error similar to the one below where. I've tried switching to ? syntax but i get the same error.
If someone could ELI5 what the difference is and what exactly database injection is and if what I'm doing in the first attempt qualifies as string concatenation that I should be trying to avoid.
Thank you so much!
If a column name or alias contains spaces, you need to put it in backticks.
query = f'SELECT company_name AS `{new_name}` from company_directory'
You can't use a placeholder for identifiers like table and column names or aliases, only where expressions are allowed.
You can't make a query parameter in place of a column alias. The rules for column aliases are the same as column identifiers, and they must be fixed in the query before you pass the query string.
So you could do this:
query = f"SELECT company_name AS `{'Company Name'}` from company_directory'
cursor.execute(query)
INTRO -
In the below python snippet,
I'm querying and fetching users' results from MySQL with the all(), then iterating the result and adding an address to a list of addresses related to a user, nothing special.
PROBLEM -
until now, I have always did it like this -
address = Address(...)
users = db.query(User).all()
for user in users :
user.addresses.append(address)
db.add(user)
db.commit()
so why when using the "SQL Expression Language" I need to iterate the result this way?
(when omitting the model notation it throws "Could not locate column in row for column")
stmt = select(User).join(Country, User.country_id == Country.id).where(Country.iso_code == iso_code).outerjoin(User.addresses)
related_users: Optional[List[User]] = db.execute(stmt).all()
if related_users:
address_in_db = self.get_or_create_address(...)
for user in related_users:
user.User.addresses.append(address_in_db ) # why this is not user.addresses.append(address)
db.add(user.User) # same here, why not just user
db.commit()
I have this method that creates the query and passes two string parameters. But when I test this it has escape characters '' before the single quote '''.
The query can only accept native queries in string form
I also tried string.replace method but doesnt work
replace('\\', '')
Here is the code
def update_query(self, status, row_id):
return '''UPDATE TABLE SET STATUS = {0} WHERE ID = {1}'''.format(status, row_id)
Here is the sample output:
'UPDATE TABLE SET STATUS = 'Success' WHERE ID = 1'
Thank you
You can also use f-string for formatting your string
def update_query(self,status, row_id):
return f"UPDATE TABLE SET STATUS = '{status}' WHERE ID = {row_id}"
>>> update_query("Success",1)
"UPDATE TABLE SET STATUS = 'Success' WHERE ID = 1"
I think you absolutely should be using prepared statements here, which the other answers don't seem to be recommending (for whatever reason). Try using something along these lines:
sql = "UPDATE TABLE SET STATUS = :status WHERE ID = :id"
cursor.prepare(sql)
cursor.execute(None, {'status':status, 'id':row_id})
One advantage of using prepared statements here is that it frees the user from having to worry about how to properly escape the literal placeholders in the query. Instead, we only need to bind a variable with the correct type to the statement, and Oracle will handle the rest.
you need to add \ in the code
def update_query(self, status, row_id):
return '''UPDATE TABLE SET STATUS = \'{0}\' WHERE ID = {1}'''.format(status, row_id)
I want to choose a field to Update from my sqlite3 db using postman by utilizing request.data. However, I receive this error "OperationalError at /
near "?": syntax error". I tried this code
def put(self,request,*args,**kwargs):
connection = sqlite3.connect('/Users/lambda_school_loaner_182/Documents/job-search-be/jobsearchbe/db.sqlite3')
cursor = connection.cursor()
req = request.data
for key in req:
if key == id:
pass
else:
print(key)
cursor.execute("UPDATE users SET ? = ? WHERE id = ?;",(key,req[key],req['id']) )
connection.commit()
cursor.execute("SELECT * FROM users WHERE id=?", (request.data['id'],))
results = cursor.fetchall()
data = []
# if request.data['id']
for row in results:
object1 = {}
col_name_list = [tuple[0] for tuple in cursor.description]
for x in range(0,len(col_name_list) ):
object1[col_name_list[x]] = row[x]
data.append(object1)
cursor.close()
# serializer =PostSerializer(data = request.data )
# if serializer.is_valid():
# serializer.save()
return Response(data)
You won't be able to use ? for identifiers (the database structures, like table and column names). You will need to use string interpolation to put in the column name.
f"UPDATE users SET {key} = ? WHERE id = ?"
? are basically for values (user-supplied data).
https://docs.python.org/3/library/sqlite3.html
Usually your SQL operations will need to use values from Python variables. You shouldn’t assemble your query using Python’s string operations because doing so is insecure; it makes your program vulnerable to an SQL injection attack (see https://xkcd.com/327/ for humorous example of what can go wrong).
Instead, use the DB-API’s parameter substitution. Put ? as a placeholder wherever you want to use a value, and then provide a tuple of values as the second argument to the cursor’s execute() method. (Other database modules may use a different placeholder, such as %s or :1.)
I have created a database with MySQLdb.
In database I have a table with name student with columns:
id(is int),
id_user(is int),
f_name(is str),
l_name(is str)
I want to update a row.
My code is below:
db=mdb.connect(host="localhost", use_unicode="True", charset="utf8",
user="", passwd="", db="test")
# prepare a cursor object using cursor() method
cursor = db.cursor()
sql="""SELECT id_user FROM student"""
try:
# Execute the SQL command
cursor.execute(sql)
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
rows = cursor.fetchall()
the=int(7)
se=str('ok')
for row in rows:
r=int(row[0])
if r==the:
sql2 = """UPDATE student
SET f_name=%s
WHERE id_user = %s"""% (se,the)
# Execute the SQL command
cursor.execute(sql2)
# Commit your changes in the database
db.commit()
db.rollback()
# disconnect from server
db.close()
When I run it I take the error there is column with name ok why?
Can anyone help me find what I am doing wrong please?
str doesn't wrap its argument in quotation marks, so your statement is this:
UPDATE student SET f_name=ok WHERE id_user = 7
when it needs to be this:
UPDATE student SET f_name='ok' WHERE id_user = 7
So, either change this line:
SET f_name=%s
to this:
SET f_name='%s'
or else change this line:
se=str('ok')
to this:
se="'" + str('ok') + "'"
Though I recommend reading about SQL injection, which will become a concern as soon as you start using user-supplied data instead of hard-coded values.
You should run the query like this:
sql2 = """UPDATE student
SET f_name = %s
WHERE id_user = %s"""
cursor.execute(sql2, (se, the))
Don't use string interpolation, let the database driver handle passing the parameters for you. Otherwise you have to deal with syntax errors like this, or worse, SQL injection.
More details here.
You should always enclose your data with quotes.
Instead of %s solely use '%s' the only types you dont need it are numeric ones, but even there i would enclose %d with '%d' cos it is more save.
And you should use at least db.escape_string(your_data) before inserting or updating same values into your database.
Or have a look at the pdo-using style of mysqldb:
http://mysql-python.sourceforge.net/MySQLdb.html#some-examples
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))