Posted on

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.