Yes. When you turn on ORM query logging, many libraries print the SQL and an excerpt of the parameters bound to it, which can include emails, names and tokens. In SQLAlchemy, set hide_parameters to True so values are replaced with a placeholder in logs and in error text.
Why this catches teams out
Query logging is a normal debugging step. Someone sets echo to True, finds the slow query, and forgets to turn it off. Or a shared logging configuration sends INFO output from the database layer to a central log system. Now every login query writes the email and every update writes the new value.
Those logs often have wider access than the database and longer retention. A support engineer who could never run a query on production can read the log index. Personal data in logs also complicates deletion requests, because you now have copies in a second place.
What SQLAlchemy documents
The SQLAlchemy docs on engine configuration say the logging emitted by the engine indicates an excerpt of the SQL parameters present for a statement. To prevent these parameters from being logged for privacy purposes, they point to the create_engine hide_parameters flag. The flag was added in version 1.3.8.
The reference for create_engine states that when set to True, statement parameters will not be displayed in INFO logging, nor formatted into the string representation of StatementError objects. The second part matters: exceptions are another path by which values reach logs and error trackers.
engine = create_engine(url, echo=True, hide_parameters=True)
The documentation example shows a statement selecting a named private value, and the log line then reads that SQL parameters are hidden due to hide_parameters.
Where else parameters appear
| Place | Why it leaks |
|---|---|
| ORM debug or echo output | Prints SQL plus bound values |
| Exception messages | Some errors include the statement and values |
| Slow query logs on the server | Depends on database settings |
| Error trackers | Capture exception text and local variables |
| Application traces | May record query text and arguments |
Check the equivalent switch in your own ORM and driver. We have not verified one for every library here, so read the logging section of your ORM's documentation and test it by running a query with a fake secret in the parameter.
A practical routine
- Search your configuration for echo, debug or verbose query logging flags.
- Make sure they are off in production, and keep them in a development profile only.
- Where you need query logs in production, enable the hide parameters option or its equivalent.
- Run a test with a canary value, such as a fake token string, and search your logs for it.
- Check your error tracker for the same canary after forcing an exception.
- Review the database server's own logging. See PostgreSQL log settings that avoid leaking secrets.
The canary test is the fastest way to find what your stack really does.
Related reading
For the general rule, read what never to log. It lists values that should never reach a log line even in development.
Safeguard scans dependencies, including ORMs and logging libraries, and can open fix pull requests when you turn that feature on. A free scan is at gold.safeguard.sh/scan.
Quick check
Does hide_parameters hide the SQL text too?
No. The docs describe it as hiding statement parameters, not the SQL string itself.
Is it on by default?
The docs present it as a flag you enable. Check your version and configuration.
Does it cover other ORMs?
No. It is a SQLAlchemy setting. Check your library's logging documentation.
Sources
Last reviewed: 19 October 2026.