Source code for codegen_database.types.postgis

from __future__ import annotations

import json
from dataclasses import asdict, dataclass
from typing import Any

from sqlalchemy import cast, func, literal_column
from sqlalchemy import types as sa_types
from sqlalchemy.dialects.postgresql import JSONB
from sqlalchemy.types import UserDefinedType


[docs] @dataclass(frozen=True, kw_only=True) class StdAddr: building: str = "" house_num: str = "" predir: str = "" qual: str = "" pretype: str = "" name: str = "" suftype: str = "" sufdir: str = "" ruralroute: str = "" extra: str = "" city: str = "" state: str = "" country: str = "" postcode: str = "" box: str = "" unit: str = ""
class _StdAddrColumn(UserDefinedType[StdAddr]): cache_ok = True def get_col_spec(self, **_kw: Any) -> str: # noqa: ANN401 return "stdaddr"
[docs] class STDADDR(sa_types.TypeDecorator[StdAddr]): impl = _StdAddrColumn cache_ok = True
[docs] def column_expression(self, colexpr: Any) -> Any: # noqa: ANN401 return func.to_jsonb(colexpr, type_=self)
[docs] def process_result_value( self, value: Any, # noqa: ANN401 dialect: Any, # noqa: ANN401, ARG002 ) -> StdAddr | None: if value is None: return None return StdAddr(**{k: (v or "") for k, v in value.items()})
[docs] def bind_expression(self, bindvalue: Any) -> Any: # noqa: ANN401 return func.jsonb_populate_record( literal_column("NULL::stdaddr"), cast(bindvalue, JSONB), )
[docs] def process_bind_param( self, value: Any, # noqa: ANN401 dialect: Any, # noqa: ANN401, ARG002 ) -> str | None: if value is None: return None if isinstance(value, StdAddr): return json.dumps( {k: (v or None) for k, v in asdict(value).items()} ) msg = f"Expected StdAddr, got {type(value).__name__}" raise ValueError(msg)