Either of these should do it.
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}.")
OR
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 PEP 249 covers the API that database libraries should follow for consistency in Python.
Under the execute
method:
Parameters may be provided as sequence or mapping and will be bound to variables in the operation.
Generally, I try to always use a mapping (e.g. dict
) in order to have some easy to follow clarity for what goes where in the SQL. Especially so when I need to repeat the same one in several places.
I may do a sequence (e.g. list
) for a short query with only one or two parameters.
From comments, to clarify there are two problems with the questions attempt at parameterization. First, the "parameters" argument to Cursor.execute() needs to be a sequence or mapping type. Second the parameterization action on the query will handle any required quoting, so the single quotes around the parameter marker (i.e. '%s'
to only %s
) were causing a less understandable error message.
The lack of quoting is because the parameterization is making the query safe, so nothing else written in the SQL statement itself has to do anything. Unfortunately, a simple message like "SQL syntax error" does not make that super obvious. The best thing I can find in the documentation about this is the Type Objects and Constructors. The pyscopg2 documentation does specifically have a section about quoting.