sqlalchemy/sqlalchemy · error · ArgumentError
Could not find a SQL type for type {extracted_type} obtained
Error message
Could not find a SQL type for type {extracted_type} obtained from annotation {annotation} in attribute '{base.__name__}.{name}' What it means
After extracting a Python type from a Named[...] / Column[...] annotation, SQLAlchemy looks it up in its built-in python-to-SQL type map (sqltypes._type_map). If the Python type has no registered SQL equivalent (e.g. dict, complex, a custom class), _get_sqltype returns None and ArgumentError is raised showing both the extracted Python type and the original annotation.
Source
Thrown at lib/sqlalchemy/sql/_annotated_cols.py:286
if not dunders_re.match(n)
]
# --
for name, obj, annotation in items:
if obj is None:
assert annotation is not None
# no attribute, just annotation
extracted_type = _collect_annotation(
table_columns_cls, name, base.__module__, annotation
)
if extracted_type is _NoArg.NO_ARG:
raise ArgumentError(
"No type information could be extracted from "
f"annotation {annotation} for attribute "
f"'{base.__name__}.{name}'"
)
sqltype = _get_sqltype(extracted_type)
if sqltype is None:
raise ArgumentError(
f"Could not find a SQL type for type {extracted_type} "
f"obtained from annotation {annotation} in "
f"attribute '{base.__name__}.{name}'"
)
columns[name] = Column(
name,
sqltype,
nullable=sa_typing.includes_none(extracted_type),
)
elif isinstance(obj, Column):
# has attribute attribute
# _DeclarativeMapperConfig._produce_column_copies
# as with orm this case is not supported
for fk in obj.foreign_keys:
if (
fk._table_column is not None
and fk._table_column.table is None
):View on GitHub (pinned to d9b44cb731)
Solutions
- Use a SQL type directly via a Column instance: `data = Column(JSON)` or `data: Named[str] = Column(JSON)`
- Pick a supported builtin Python type (str, int, float, bytes, bool, Decimal, datetime, UUID) for inference
- Register a custom TypeEngine decorator and reference it explicitly through a Column instance rather than relying on the python-type map
Example fix
# before
class Cols(TypedColumns):
payload: Named[dict] # no SQL type for dict
# after
from sqlalchemy import JSON
class Cols(TypedColumns):
payload = Column(JSON) Defensive patterns
Strategy: validation
Validate before calling
import datetime, decimal, uuid
from sqlalchemy import types as sqltypes
TYPE_MAP = {
int: sqltypes.Integer, str: sqltypes.String, float: sqltypes.Float,
bool: sqltypes.Boolean, bytes: sqltypes.LargeBinary,
datetime.datetime: sqltypes.DateTime, datetime.date: sqltypes.Date,
datetime.time: sqltypes.Time, decimal.Decimal: sqltypes.Numeric,
uuid.UUID: sqltypes.Uuid,
}
def ensure_mappable(py_type) -> None:
if py_type not in TYPE_MAP:
raise ValueError(
f"No built-in SQL type for {py_type!r}; "
"register a TypeDecorator or set the type on the Column explicitly."
) Prevention
- Stick to Python primitives SQLAlchemy maps automatically (int, str, float, bool, bytes, datetime, Decimal, UUID).
- For custom/enum types, subclass `sqlalchemy.types.TypeDecorator` and annotate with that subclass.
- If a type is exotic, pass it directly to Column (`Column(type_=MyType())`) instead of relying on the annotation alone.
When it happens
Trigger: Annotating a column with an unsupported Python type: `data: Named[dict]`, `val: Named[complex]`, or `obj: Named[MyCustomClass]` where MyCustomClass has no TypeEngine mapping. The supported set covers bool, int, float, str, bytes, datetime, Decimal, UUID, etc.
Common situations: Assuming any Python type can be mapped (e.g. wanting JSON and writing Named[dict] instead of using the JSON SQL type), or using domain/dataclass types as column annotations without registering a SQL type decorator.
Related errors
- No type information could be extracted from annotation {anno
- Python typing annotation is required for attribute '{base.__
- Could not interpret annotation {raw_annotation} for attribut
- Cannot instantiate a TypedColumns object.
- TypedColumns subclasses may not define methods. Found {sorte
AI-assisted analysis of sqlalchemy/sqlalchemy@d9b44cb731 (2026-08-01).
Data as JSON: /data/errors/78b363f53b80772f.json.
Report an issue: GitHub.