使用 Python 和 mySQL 的动态 SQL 查询
Dynamic SQL Queries with Python and mySQL
我有多个表在网格中的值更改后更新。这些表并不总是具有相同的键或列,因此我无法明确命名列或格式。唯一不变的是键所在的列。我知道我目前这样做的方式不正确,让我容易受到注入攻击。
我还 运行 遇到一个问题,其中某些值包含在 SQL 语句中引发错误的键。例如,更新 WHERE email = t'est@email.com
.
我不太确定写这些语句的正确方法。我做了一些研究,看到了多种用于不同目的的方法,但不确定哪种方法合适。我希望尽可能动态地做到这一点。谁能指出我正确的方向?
要连接:
import mysql.connector as sql
import MySQLdb
#Connect
self.db_name = 'database'
self.server = 'server'
self.user_id = 'user'
self.pw = 'password'
try:
self.db_con = MySQLdb.connect(user=self.user_id,password=self.pw,database=self.db_name,
host=self.server,charset='utf8',autocommit=True)
self.cursor = self.db_con.cursor()
except:
print("Error connecting")
SQL 报表:
key_id = str("'") + self.GetCellValue(event.GetRow(),1) + str("'")
target_col = self.GetColLabelValue(event.GetCol())
key_col = self.GetColLabelValue(1)
nVal = str("'") + self.GetCellValue(event.GetRow(),event.GetCol()) + str("'")
#SQL STATEMENTS
sql_update = "UPDATE " + tbl + " SET " + target_col + " = " + nVal + " WHERE " + key_col + " = " + key_id + ""
#INSERT
sql_update = ("INSERT INTO " + str(self.tbl) + "(" + self.key_col + ")" + "VALUES (" + str("'") + str(val) + str("'") + ")")
#DELETE
sql_update = "DELETE FROM " + tbl + " WHERE " + self.key_col + " = " + self.key_id + ""
#SELECT
sql_query = "SELECT * FROM " + self.tbl
#Excecute
try:
self.cursor.execute(sql_update)
except:
print('Error')
self.db_con.rollback()
数据库对“引用”identifiers(table 和列名等)和 values(数据)有不同的表示法。
MySQL 使用 反引号 来引用标识符。对于值,最好使用连接器包提供的参数替换机制:它更有可能正确处理像嵌入引号这样棘手的情况,并且会降低 SQL 注入的风险。
这是一个插入的例子;相同的技术可用于其他类型的查询。
key_id = str("'") + self.GetCellValue(event.GetRow(),1) + str("'")
target_col = self.GetColLabelValue(event.GetCol())
key_col = self.GetColLabelValue(1)
nVal = str("'") + self.GetCellValue(event.GetRow(),event.GetCol()) + str("'")
#INSERT (using f-strings for brevity)
sql_update = (f"INSERT INTO `{self.tbl}` (`{self.key_col}`) VALUES (%s)")
# Pass the statement and values to cursor.execute.
# The values are assumed to be a sequence, so a single value should be
# placed in a tuple or list.
self.cursor.execute(sql_update, (nVal,))
如果您有多个列/值对,您可以这样做:
cols = ['A', 'B', 'C']
vals = ['a', 'b', 'c']
col_names = ','.join([f'`{c}`' for c in cols])
values_placeholder = ','.join(['%s'] * len(cols))
sql_update = (f"INSERT INTO `{self.tbl}` (col_names) VALUES ({values_placeholder})")
self.cursor.execute(sql_update, vals)
值不仅是用于插入的数据,也是我们用于比较的数据,例如在 WHERE
子句中。因此,可以像这样创建带有过滤器的更新语句:
sql_update = (f"UPDATE `{tbl}` SET (`{target_col}`) = (%s) WHERE (`{key_col}`) = %s")
self.cursor.execute(sql_update, (nVal, key_id))
然而,有时 SET
或 WHERE
子句的目标可能是一列,例如我们想根据行中的其他值进行更新。例如,对于 key_col
等于 other_key_col
:
的所有行,此语句会将 target_col
设置为 other_col
的值
sql_update = (f"UPDATE `{tbl}` SET (`{target_col}`) = `{other_col}` WHERE (`{key_col}`) = `{other_key_col}`")
self.cursor.execute(sql_update)
我有多个表在网格中的值更改后更新。这些表并不总是具有相同的键或列,因此我无法明确命名列或格式。唯一不变的是键所在的列。我知道我目前这样做的方式不正确,让我容易受到注入攻击。
我还 运行 遇到一个问题,其中某些值包含在 SQL 语句中引发错误的键。例如,更新 WHERE email = t'est@email.com
.
我不太确定写这些语句的正确方法。我做了一些研究,看到了多种用于不同目的的方法,但不确定哪种方法合适。我希望尽可能动态地做到这一点。谁能指出我正确的方向?
要连接:
import mysql.connector as sql
import MySQLdb
#Connect
self.db_name = 'database'
self.server = 'server'
self.user_id = 'user'
self.pw = 'password'
try:
self.db_con = MySQLdb.connect(user=self.user_id,password=self.pw,database=self.db_name,
host=self.server,charset='utf8',autocommit=True)
self.cursor = self.db_con.cursor()
except:
print("Error connecting")
SQL 报表:
key_id = str("'") + self.GetCellValue(event.GetRow(),1) + str("'")
target_col = self.GetColLabelValue(event.GetCol())
key_col = self.GetColLabelValue(1)
nVal = str("'") + self.GetCellValue(event.GetRow(),event.GetCol()) + str("'")
#SQL STATEMENTS
sql_update = "UPDATE " + tbl + " SET " + target_col + " = " + nVal + " WHERE " + key_col + " = " + key_id + ""
#INSERT
sql_update = ("INSERT INTO " + str(self.tbl) + "(" + self.key_col + ")" + "VALUES (" + str("'") + str(val) + str("'") + ")")
#DELETE
sql_update = "DELETE FROM " + tbl + " WHERE " + self.key_col + " = " + self.key_id + ""
#SELECT
sql_query = "SELECT * FROM " + self.tbl
#Excecute
try:
self.cursor.execute(sql_update)
except:
print('Error')
self.db_con.rollback()
数据库对“引用”identifiers(table 和列名等)和 values(数据)有不同的表示法。
MySQL 使用 反引号 来引用标识符。对于值,最好使用连接器包提供的参数替换机制:它更有可能正确处理像嵌入引号这样棘手的情况,并且会降低 SQL 注入的风险。
这是一个插入的例子;相同的技术可用于其他类型的查询。
key_id = str("'") + self.GetCellValue(event.GetRow(),1) + str("'")
target_col = self.GetColLabelValue(event.GetCol())
key_col = self.GetColLabelValue(1)
nVal = str("'") + self.GetCellValue(event.GetRow(),event.GetCol()) + str("'")
#INSERT (using f-strings for brevity)
sql_update = (f"INSERT INTO `{self.tbl}` (`{self.key_col}`) VALUES (%s)")
# Pass the statement and values to cursor.execute.
# The values are assumed to be a sequence, so a single value should be
# placed in a tuple or list.
self.cursor.execute(sql_update, (nVal,))
如果您有多个列/值对,您可以这样做:
cols = ['A', 'B', 'C']
vals = ['a', 'b', 'c']
col_names = ','.join([f'`{c}`' for c in cols])
values_placeholder = ','.join(['%s'] * len(cols))
sql_update = (f"INSERT INTO `{self.tbl}` (col_names) VALUES ({values_placeholder})")
self.cursor.execute(sql_update, vals)
值不仅是用于插入的数据,也是我们用于比较的数据,例如在 WHERE
子句中。因此,可以像这样创建带有过滤器的更新语句:
sql_update = (f"UPDATE `{tbl}` SET (`{target_col}`) = (%s) WHERE (`{key_col}`) = %s")
self.cursor.execute(sql_update, (nVal, key_id))
然而,有时 SET
或 WHERE
子句的目标可能是一列,例如我们想根据行中的其他值进行更新。例如,对于 key_col
等于 other_key_col
:
target_col
设置为 other_col
的值
sql_update = (f"UPDATE `{tbl}` SET (`{target_col}`) = `{other_col}` WHERE (`{key_col}`) = `{other_key_col}`")
self.cursor.execute(sql_update)