Skip to content

Instantly share code, notes, and snippets.

@Finndersen
Created January 24, 2025 18:49
Show Gist options
  • Save Finndersen/89ef18baf1cade3fe71abda75167e14a to your computer and use it in GitHub Desktop.
Save Finndersen/89ef18baf1cade3fe71abda75167e14a to your computer and use it in GitHub Desktop.
Helper utility to construct a Pydantic Model from a SQLAlchemy model. Based on https://github.com/wezhai/sqlalchemy-to-pydantic/ with some tweaks
from collections.abc import Container
from pydantic import BaseModel, ConfigDict, create_model
orm_config = ConfigDict(from_attributes=True)
def sqlalchemy_to_pydantic(
db_model: type,
*,
config: ConfigDict | None = None,
exclude: Container[str] | None = None,
nullable_fields: Container[str] | None = None,
) -> type[BaseModel]:
table = db_model.metadata.tables[db_model.__tablename__]
fields = {}
config = config or orm_config
exclude = exclude or set()
nullable_fields = nullable_fields or set()
for column in table.columns:
name = column.name
if name in exclude:
continue
python_type: type | None = None
if hasattr(column.type, "impl"):
if hasattr(column.type.impl, "python_type"):
python_type = column.type.impl.python_type
elif hasattr(column.type, "python_type"):
python_type = column.type.python_type
assert python_type, f"Could not infer python_type for {column}"
if column.nullable or column.name in nullable_fields:
fields[name] = (python_type | None, None)
else:
fields[name] = (python_type, ...)
pydantic_model = create_model(db_model.__name__, __config__=config, **fields)
return pydantic_model
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment