We avoid constructing database queries using string formatting to prevent security issues. SQL injection attacks stem from a lack of proper escaping and building queries directly from untrusted input strings.
Instead, we use parameter passing to the database engine. For example:
SELECT * FROM people WHERE name = ?
We send this query and the parameters separately to the database. Most modern database systems support this approach.
In SQLite 3 with Python, we use it like this:
query = "SELECT * FROM people WHERE name = ?"
params = (name,)
db_result = cursor.execute(query, params)
However, when debugging, we may need to see the actual queries sent to the database—for instance, when data types are important or when we suspect a column is receiving a string instead of an integer.
In these cases, rather than manually reconstructing the query, we can use the set_trace_callback feature available in Python 3.3 and later:
connection.set_trace_callback(print)
The argument can be any function (such as print or a logger function) or None to disable tracing. This makes it easy to integrate with Python’s standard logging module.