How to convert SQLAlchemy row object to a Python dict?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In modern SQLAlchemy, the safest way to convert a row result to a Python dictionary is to use the row’s mapping interface instead of poking at private internals. The usual answer is dict(row._mapping), but the best approach depends on whether you are dealing with Core rows, ORM objects, or full result sets.
Converting a Single Core Row
For SQLAlchemy Core result rows, use _mapping:
This produces:
That is the standard modern pattern for row objects returned from SQLAlchemy statements.
Converting Many Rows at Once
If you want dictionaries for every row, iterate and convert each mapping:
This is straightforward and keeps the conversion explicit.
An Even Cleaner Result API
SQLAlchemy also offers a mappings-oriented result view:
The returned objects behave like dictionaries already. If you need plain dict instances specifically, you can still wrap them with dict(...).
This is often the cleanest option when your downstream code is already expecting mapping-like rows.
ORM Objects Are Different
If you queried ORM model instances, those are not row mappings. They are normal Python objects with SQLAlchemy state attached.
Then:
Calling __dict__ directly on ORM objects is usually a bad idea because it includes internal SQLAlchemy state you do not want to expose.
Label Columns Intentionally
If your query includes expressions or joins, label columns so the resulting dictionary keys are stable.
Clear labels make API output and debugging much easier.
Watch for JSON Serialization Types
Some database values are not directly JSON-friendly:
- '
datetime' - '
Decimal' - '
UUID'
If your dict is headed to an API response, convert those values in one serializer layer so the output format stays predictable.
The row-to-dict step solves structure, but not necessarily final serialization.
Common Pitfalls
One common mistake is using old row internals from outdated SQLAlchemy examples. SQLAlchemy changed row behavior across versions, so older tricks are often fragile.
Another issue is using __dict__ on ORM models and leaking _sa_instance_state into the output.
A third pitfall is forgetting to label complex query columns, which can produce confusing or unstable dictionary keys.
Summary
- For SQLAlchemy Core rows, use
dict(row._mapping). - For full result sets,
result.mappings()is often the cleanest API. - ORM model instances should usually expose an explicit
to_dict()method. - Label selected columns clearly for stable output keys.
- Row-to-dict conversion is only one step; JSON serialization concerns may still remain.

