26 lines
898 B
Python
26 lines
898 B
Python
from __future__ import annotations
|
|
from functools import lru_cache
|
|
from typing import NamedTuple, Any, Dict, Tuple
|
|
from sqlalchemy import inspect
|
|
from sqlalchemy.orm import Mapper
|
|
|
|
class RelInfo(NamedTuple):
|
|
key: str
|
|
uselist: bool
|
|
target_cls: type | None
|
|
|
|
@lru_cache(maxsize=512)
|
|
def mapper_info(model: type) -> Dict[str, Any]:
|
|
m: Mapper = inspect(model)
|
|
cols = tuple(prop.key for prop in m.column_attrs)
|
|
rels = { r.key: RelInfo(r.key, bool(r.uselist), getattr(r.mapper, "class_", None))
|
|
for r in m.relationships }
|
|
pks = tuple(c.key for c in m.primary_key)
|
|
table = getattr(model, "__table__", None)
|
|
return {"cols": cols, "rels": rels, "pks": pks, "table": table}
|
|
|
|
def rel_map(model: type) -> Dict[str, RelInfo]:
|
|
return mapper_info(model)["rels"]
|
|
|
|
def column_names_for_model(model: type) -> Tuple[str, ...]:
|
|
return mapper_info(model)["cols"]
|