Skip to content

feat(python-codegen): @column field naming, server-default exprs, --entities allowlist#79

Merged
dmealing merged 2 commits into
mainfrom
feat/py-codegen-column-server-default-entities
Jun 26, 2026
Merged

feat(python-codegen): @column field naming, server-default exprs, --entities allowlist#79
dmealing merged 2 commits into
mainfrom
feat/py-codegen-column-server-default-entities

Conversation

@dmealing

Copy link
Copy Markdown
Member

Motivation

Surfaced by generating Python record models from the same entity metadata that drives the TypeScript Drizzle layer (one cross-language source of truth). Three consumer-facing gaps blocked that, all in the Python port's entity_model generator + CLI — no metamodel/registry change, so no cross-port conformance reconciliation is needed.

Changes

1. @column-aware Pydantic field naming. The generator emitted field.name verbatim, so an entity authored camelCase for the TS port (callPurpose + @column: call_purpose) produced camelCase Python fields that don't match the DB columns. The Pydantic field name is now field.column ?? field.name — one entity feeds both languages idiomatically (camelCase TS property, snake_case Python field = the physical column). Backward-compatible: a model with no @column emits byte-identically.

2. Server-side default expressions are no longer rendered as Python literal defaults. A string @default matching the SQL-expression patterns (now, now(), current_timestamp/date/time, anything ending in () such as gen_random_uuid()) is DB-filled — so id: uuid.UUID = "gen_random_uuid()" was invalid. Such a field now carries no Python default (keeps its required/optional shape). Literal defaults (bool/int/str/enum) are unchanged. Mirrors the TS column-mapper.ts SQL_EXPR_PATTERNS so both ports agree on what counts as an expression.

3. metaobjects gen --entities <names> allowlist. The whole model is still loaded (so extends bases and @objectRef VOs resolve), but only the named entities are emitted — generate a subset of a shared model without splitting the metadata. Wired through gen and verify --codegen; run_gen already supported entity_filter.

Tests

New regression tests in test_entity_model.py (column override, fallback, server-default-expr vs literal) and test_cli.py (entities allowlist emit + verify in sync). Full tests/codegen suite green except two pre-existing test_cli_staleness_nudge failures unrelated to this change (they fail on clean origin/main too).

Also bumps the Python port to 0.12.0 (backward-compatible minor; aligns with the 0.12.x line).

dmealing and others added 2 commits June 26, 2026 05:26
…ntities allowlist

Three consumer-facing gaps surfaced by generating Python record models from the SAME
entity metadata that drives the TypeScript Drizzle layer:

1. @column-aware Pydantic field naming. The entity/value generator emitted `field.name`
   verbatim, so a model authored camelCase for the TS port (`callPurpose` +
   `@column: call_purpose`) produced camelCase Python fields that don't match the DB
   columns. The Pydantic field name is now `@column` when present, else `field.name` —
   one entity feeds both languages idiomatically (camelCase TS property, snake_case
   Python field = the physical column). Backward-compatible: no @column emits identically.

2. Server-side default EXPRESSIONS are no longer rendered as Python literal defaults.
   A string @default matching the SQL-expression patterns (now, now(),
   current_timestamp/date/time, anything ending in `()` such as gen_random_uuid()) is
   DB-filled, so emitting `id: uuid.UUID = "gen_random_uuid()"` was wrong. Such a field
   now carries no Python default (keeps its required/optional shape); literal defaults
   (bool/int/str/enum) are unchanged. Mirrors the TS column-mapper's SQL_EXPR_PATTERNS
   so both ports agree on what counts as an expression.

3. `metaobjects gen --entities <names>` allowlist. The whole model is still loaded (so
   `extends` bases and @objectref VOs resolve), but only the named entities are emitted
   — generate a subset of a shared model without splitting the metadata. Wired through
   `gen` and `verify --codegen` (run_gen already supported entity_filter).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Minor bump for the backward-compatible codegen features in the previous commit
(@column field naming, server-default expressions, --entities allowlist) and to
align the Python port with the 0.12.x line. pyproject + uv.lock self-version only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dmealing
dmealing merged commit 8352079 into main Jun 26, 2026
29 checks passed
@dmealing
dmealing deleted the feat/py-codegen-column-server-default-entities branch June 26, 2026 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant