在python中参数化delete sql语句时遇到问题

lkaoscv7  于 2021-07-29  发布在  Java
关注(0)|答案(2)|浏览(335)

我正在编写一个python3脚本来处理mysql数据库。使用mysql.connector功能。
我正试图写一个删除命令。我可以让它使用静态字符串,但我不能让它使用参数化语句。
这个有效:

sql = "DELETE FROM mytable where report_dt < '" + str(report_date) + "'"
try:
    mycursor.execute(sql)
    mydb.commit()

这个失败了:

sql = "DELETE FROM mytable where report_dt < '%s'"
try:
    mycursor.execute(sql, report_date)
    mydb.commit()

报表\u date var来自datetime.datetime.now(),格式如下:
str(报告日期)返回:“2020-06-09 10:59:11”
没有错误消息…它只是没有实际删除它应该删除的行。

vqlkdk9b

vqlkdk9b1#

看起来解决方案是上面几个答案的混合:

sql = "DELETE FROM mytable where report_dt < %s"
try:
    mycursor.execute(sql, [report_date])
    mydb.commit()

删除%s周围的单引号,并在报表日期变量周围使用括号。
当它是一个静态文本条目时,单引号是必需的,但是在参数化过程中,它的工作方式显然不同。
谢谢大家!

4uqofj5v

4uqofj5v2#

这两个都可以。

sql = "DELETE FROM mytable WHERE report_dt < %(date)s;"
try:
    mycursor.execute(sql, {'date': str(report_date)})
    mydb.commit()
except:
    print(f"Error deleting report from {report_date}.")

sql = "DELETE FROM mytable WHERE report_dt < %s;"
try:
    mycursor.execute(sql, [str(report_date)])
    mydb.commit()
except:
    print(f"Error deleting report from {report_date}.")

python pep249涵盖了数据库库在python中保持一致性所应遵循的api。
execute 方法:
参数可以作为序列或Map提供,并将绑定到操作中的变量。
通常,我总是尝试使用Map(例如。 dict )为了更清楚地了解sql中的内容。尤其是当我需要在几个地方重复同一个。
我可以做一个序列(例如。 list )对于只有一个或两个参数的短查询。
从评论中,澄清了两个问题,并尝试用参数化的问题。首先,cursor.execute()的“parameters”参数必须是序列或Map类型。其次,查询上的参数化操作将处理任何必需的引号,因此参数标记周围的单引号(即。 '%s' 仅适用于 %s )导致了一个不太容易理解的错误消息。
缺少引号是因为参数化使查询安全,所以在sql语句本身中编写的其他语句不必做任何事情。不幸的是,像“sql语法错误”这样的简单消息并不能使这一点变得非常明显。在文档中我能找到的最好的东西就是类型对象和构造函数。pyscopg2文档确实有一个关于引用的部分。

相关问题