Commit c845c69
committed
chore(client): emit Mapped[T] field types on Cached* classes (drop col()/cast() ergonomics tax)
Closes #625-spike-revisit. Generator now wraps every cache-table field's
type in ``Mapped[T]`` so type checkers see ``CachedX.field`` as
``InstrumentedAttribute[T]`` (with ``.in_/.is_/.desc/.ilike``). The
36 ``sqlmodel.col()`` wrappers and 4 ``cast(QueryableAttribute, ...)``
calls landed in #624 are no longer needed and have been removed.
The runtime path is unchanged: a small ``_mapped_shim.py`` module
defines ``Mapped`` as ``sqlalchemy.orm.Mapped`` under ``TYPE_CHECKING``
and as a runtime-identity class (``__class_getitem__`` returns ``T``)
otherwise. So ``Annotated[Mapped[int], Field(...)]`` evaluates to
``Annotated[int, Field(...)]`` at class-definition time — exactly what
SQLModel + pydantic 2.13 want.
The earlier #625 spike concluded "won't do" because the only working
form (``if TYPE_CHECKING / else``) doubled every field declaration.
That spike missed the runtime-identity-shim option, which the
research follow-up surfaced via SQLModel discussion #1016 and
``roman.pt/posts/pydantic-in-sqlalchemy-fields/``.
Generator changes (``scripts/generate_pydantic_models.py``):
- New pass ``wrap_cache_fields_in_mapped`` runs after every other
field-rewrite pass (those passes match ``Annotated[T, Field(...)]``
literally — running this wrap before them would leave them unable
to find their targets). It does two regex sweeps:
- ``Annotated[<type>, ...]`` → ``Annotated[Mapped[<type>], ...]``
(column fields)
- ``field: <type> = Relationship(...)`` →
``field: Mapped[<type>] = Relationship(...)`` (relationship fields,
matching SQLAlchemy 2.0's canonical shape)
- Operates on both ``Cached*`` siblings *and* the shared entity base
classes (BaseEntity, UpdatableEntity, DeletableEntity, etc.) since
``Cached*`` inherits ``id`` / ``created_at`` / ``updated_at`` /
``deleted_at`` / ``archived_at`` from those bases. Wrapping only the
Cached classes left those inherited fields as bare ``T`` for type
checkers — and those are the fields most query call sites filter on.
API classes that share the same bases inherit the wrapping too;
runtime is unaffected (Mapped → identity), and no API consumer
relies on class-level access (instance-level access stays as ``T``
per pydantic's normal field handling).
- Mapped shim import added to cache-table modules and ``base.py``.
Foundation-file cleanup (``katana_mcp_server/.../foundation/*.py``):
- Dropped 36 ``col(CachedX.field)`` wrappers across 6 files
(inventory, manufacturing_orders, sales_orders, purchase_orders,
stock_transfers, reporting) — types now resolve correctly without
the wrapper.
- Dropped 4 ``cast("QueryableAttribute[Any]", CachedX.<rel>)``
wrappers around ``selectinload`` arguments — relationship fields
are now ``Mapped[list[X]]`` so ``selectinload(CachedX.<rel>)``
type-checks natively.
- Removed corresponding unused imports (``col``, ``QueryableAttribute``,
``cast``).
Typecheck config (``pyproject.toml``):
- ``ty check`` now also excludes
``katana_public_api_client/models_pydantic/_generated/`` (matches
``pyrightconfig.json`` exclusions). Ty rejects the trailing
``= None`` default on ``Annotated[Mapped[T | None], Field(...)] = None``;
pyright accepts it. Generated files are auto-emitted, so excluding
them from in-repo type-checking is consistent with how pyright
already handles them.
Validation:
- ``uv run poe lint`` clean (ruff + ty + yamllint)
- ``uv run poe check`` clean (full validation)
- ``uv run pyright katana_mcp_server/src/`` 0 errors / 1 documented warning
- All 3,019 tests pass
This is forward-compatible: when SQLModel ships native ``Mapped[T]``
support, the shim becomes redundant and can be deleted in a one-line
PR (the generator output stays the same).
Refs: #6251 parent b82abdb commit c845c69
16 files changed
Lines changed: 609 additions & 264 deletions
File tree
- katana_mcp_server/src/katana_mcp/tools/foundation
- katana_public_api_client/models_pydantic
- _generated
- scripts
- tests
Lines changed: 11 additions & 16 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| |||
1192 | 1192 | | |
1193 | 1193 | | |
1194 | 1194 | | |
1195 | | - | |
| 1195 | + | |
1196 | 1196 | | |
1197 | 1197 | | |
1198 | 1198 | | |
| |||
1202 | 1202 | | |
1203 | 1203 | | |
1204 | 1204 | | |
1205 | | - | |
| 1205 | + | |
1206 | 1206 | | |
1207 | 1207 | | |
1208 | 1208 | | |
1209 | 1209 | | |
1210 | 1210 | | |
1211 | 1211 | | |
1212 | | - | |
| 1212 | + | |
1213 | 1213 | | |
1214 | 1214 | | |
1215 | 1215 | | |
| |||
1229 | 1229 | | |
1230 | 1230 | | |
1231 | 1231 | | |
1232 | | - | |
| 1232 | + | |
1233 | 1233 | | |
1234 | 1234 | | |
1235 | 1235 | | |
| |||
1256 | 1256 | | |
1257 | 1257 | | |
1258 | 1258 | | |
1259 | | - | |
1260 | | - | |
| 1259 | + | |
| 1260 | + | |
1261 | 1261 | | |
1262 | 1262 | | |
1263 | 1263 | | |
| |||
1276 | 1276 | | |
1277 | 1277 | | |
1278 | 1278 | | |
1279 | | - | |
1280 | | - | |
1281 | | - | |
1282 | | - | |
1283 | | - | |
1284 | | - | |
| 1279 | + | |
1285 | 1280 | | |
1286 | 1281 | | |
1287 | 1282 | | |
1288 | | - | |
| 1283 | + | |
1289 | 1284 | | |
1290 | 1285 | | |
1291 | 1286 | | |
| |||
1296 | 1291 | | |
1297 | 1292 | | |
1298 | 1293 | | |
1299 | | - | |
1300 | | - | |
| 1294 | + | |
| 1295 | + | |
1301 | 1296 | | |
1302 | 1297 | | |
1303 | 1298 | | |
| |||
Lines changed: 15 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1777 | 1777 | | |
1778 | 1778 | | |
1779 | 1779 | | |
1780 | | - | |
1781 | 1780 | | |
1782 | 1781 | | |
1783 | 1782 | | |
1784 | 1783 | | |
1785 | 1784 | | |
1786 | 1785 | | |
1787 | | - | |
| 1786 | + | |
1788 | 1787 | | |
1789 | 1788 | | |
1790 | 1789 | | |
1791 | 1790 | | |
1792 | 1791 | | |
1793 | 1792 | | |
1794 | 1793 | | |
1795 | | - | |
1796 | | - | |
1797 | | - | |
| 1794 | + | |
1798 | 1795 | | |
1799 | 1796 | | |
1800 | | - | |
| 1797 | + | |
1801 | 1798 | | |
1802 | 1799 | | |
1803 | 1800 | | |
| |||
1814 | 1811 | | |
1815 | 1812 | | |
1816 | 1813 | | |
1817 | | - | |
| 1814 | + | |
1818 | 1815 | | |
1819 | 1816 | | |
1820 | 1817 | | |
| |||
1842 | 1839 | | |
1843 | 1840 | | |
1844 | 1841 | | |
1845 | | - | |
| 1842 | + | |
1846 | 1843 | | |
1847 | 1844 | | |
1848 | 1845 | | |
| |||
1858 | 1855 | | |
1859 | 1856 | | |
1860 | 1857 | | |
1861 | | - | |
1862 | | - | |
| 1858 | + | |
| 1859 | + | |
1863 | 1860 | | |
1864 | 1861 | | |
1865 | 1862 | | |
| |||
2182 | 2179 | | |
2183 | 2180 | | |
2184 | 2181 | | |
2185 | | - | |
| 2182 | + | |
2186 | 2183 | | |
2187 | 2184 | | |
2188 | 2185 | | |
| |||
2264 | 2261 | | |
2265 | 2262 | | |
2266 | 2263 | | |
2267 | | - | |
| 2264 | + | |
2268 | 2265 | | |
2269 | 2266 | | |
2270 | | - | |
2271 | | - | |
2272 | | - | |
| 2267 | + | |
| 2268 | + | |
| 2269 | + | |
2273 | 2270 | | |
2274 | | - | |
| 2271 | + | |
2275 | 2272 | | |
2276 | 2273 | | |
2277 | 2274 | | |
2278 | 2275 | | |
2279 | 2276 | | |
2280 | | - | |
| 2277 | + | |
2281 | 2278 | | |
2282 | | - | |
2283 | | - | |
2284 | | - | |
| 2279 | + | |
2285 | 2280 | | |
2286 | 2281 | | |
2287 | 2282 | | |
| |||
Lines changed: 9 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
2013 | 2013 | | |
2014 | 2014 | | |
2015 | 2015 | | |
2016 | | - | |
2017 | 2016 | | |
2018 | 2017 | | |
2019 | 2018 | | |
| |||
2023 | 2022 | | |
2024 | 2023 | | |
2025 | 2024 | | |
2026 | | - | |
| 2025 | + | |
2027 | 2026 | | |
2028 | 2027 | | |
2029 | 2028 | | |
| |||
2056 | 2055 | | |
2057 | 2056 | | |
2058 | 2057 | | |
2059 | | - | |
| 2058 | + | |
2060 | 2059 | | |
2061 | 2060 | | |
2062 | 2061 | | |
| |||
2085 | 2084 | | |
2086 | 2085 | | |
2087 | 2086 | | |
2088 | | - | |
2089 | | - | |
| 2087 | + | |
| 2088 | + | |
2090 | 2089 | | |
2091 | 2090 | | |
2092 | 2091 | | |
| |||
2105 | 2104 | | |
2106 | 2105 | | |
2107 | 2106 | | |
2108 | | - | |
2109 | | - | |
2110 | | - | |
2111 | | - | |
2112 | | - | |
2113 | | - | |
| 2107 | + | |
2114 | 2108 | | |
2115 | 2109 | | |
2116 | 2110 | | |
2117 | | - | |
| 2111 | + | |
2118 | 2112 | | |
2119 | 2113 | | |
2120 | 2114 | | |
| |||
2123 | 2117 | | |
2124 | 2118 | | |
2125 | 2119 | | |
2126 | | - | |
2127 | | - | |
| 2120 | + | |
| 2121 | + | |
2128 | 2122 | | |
2129 | 2123 | | |
2130 | 2124 | | |
| |||
Lines changed: 5 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
793 | 793 | | |
794 | 794 | | |
795 | 795 | | |
796 | | - | |
| 796 | + | |
797 | 797 | | |
798 | 798 | | |
799 | 799 | | |
| |||
815 | 815 | | |
816 | 816 | | |
817 | 817 | | |
818 | | - | |
| 818 | + | |
819 | 819 | | |
820 | 820 | | |
821 | 821 | | |
822 | | - | |
823 | | - | |
824 | | - | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
825 | 825 | | |
826 | 826 | | |
827 | 827 | | |
| |||
Lines changed: 8 additions & 13 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
| 19 | + | |
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| |||
730 | 730 | | |
731 | 731 | | |
732 | 732 | | |
733 | | - | |
734 | 733 | | |
735 | 734 | | |
736 | 735 | | |
| |||
745 | 744 | | |
746 | 745 | | |
747 | 746 | | |
748 | | - | |
| 747 | + | |
749 | 748 | | |
750 | 749 | | |
751 | 750 | | |
| |||
767 | 766 | | |
768 | 767 | | |
769 | 768 | | |
770 | | - | |
| 769 | + | |
771 | 770 | | |
772 | 771 | | |
773 | 772 | | |
| |||
795 | 794 | | |
796 | 795 | | |
797 | 796 | | |
798 | | - | |
799 | | - | |
| 797 | + | |
| 798 | + | |
800 | 799 | | |
801 | 800 | | |
802 | 801 | | |
| |||
815 | 814 | | |
816 | 815 | | |
817 | 816 | | |
818 | | - | |
819 | | - | |
820 | | - | |
| 817 | + | |
821 | 818 | | |
822 | 819 | | |
823 | 820 | | |
824 | | - | |
| 821 | + | |
825 | 822 | | |
826 | 823 | | |
827 | 824 | | |
828 | 825 | | |
829 | 826 | | |
830 | 827 | | |
831 | 828 | | |
832 | | - | |
833 | | - | |
834 | | - | |
| 829 | + | |
835 | 830 | | |
836 | 831 | | |
837 | 832 | | |
| |||
0 commit comments