Skip to content

Skip SQLite generated columns in generate entity#3095

Open
JMLX42 wants to merge 1 commit into
SeaQL:masterfrom
JMLX42:fix/skip-sqlite-generated-columns-codegen
Open

Skip SQLite generated columns in generate entity#3095
JMLX42 wants to merge 1 commit into
SeaQL:masterfrom
JMLX42:fix/skip-sqlite-generated-columns-codegen

Conversation

@JMLX42

@JMLX42 JMLX42 commented Jun 23, 2026

Copy link
Copy Markdown

PR Info

Bug Fixes

  • sea-orm-cli generate entity no longer reverse-generates SQLite generated columns (GENERATED ALWAYS AS (...) VIRTUAL/STORED) as ordinary, writable entity fields.

Description

SQLite generated columns became discoverable when discovery switched from PRAGMA table_info to PRAGMA table_xinfo in SeaQL/sea-schema#161 — a correct fix for schema sync (#2995), where generated columns were previously invisible and sync kept re-issuing ALTER TABLE ... ADD COLUMN.

As a side effect, generate entity consumes the same discovery and now emits these columns as plain fields:

#[sea_orm(column_type = "Text", nullable)]
pub pixels: Option<i32>,

Because there is no marker distinguishing them, they land in the derived ActiveModel. Any Model::into_active_model() round-trip then includes them in INSERT/UPDATE, and SQLite rejects it:

cannot INSERT into generated column "pixels"
cannot UPDATE generated column "pixels"

Generated columns are read-only at the storage layer, so they should not be reverse-generated as writable columns. In the Entity-First workflow they are declared with #[sea_orm(extra = "GENERATED ALWAYS AS (...) VIRTUAL")], not produced by reverse codegen.

Changes

  • Add discard_generated_columns() in sea-orm-cli's generate command. In the SQLite branch, each discovered table is passed through it before TableDef::write(), removing columns whose ColumnVisibility is GeneratedVirtual or GeneratedStored.
  • Discovery itself is untouched, so schema sync keeps seeing generated columns and the Column extra causes sync to add column again #2995 fix is preserved — only the reverse-codegen path drops them.
  • Unit test test_discard_generated_columns covering both VIRTUAL and STORED columns and confirming ordinary columns are preserved in order.

This restores the pre-rc.34 generate entity behavior for generated columns. A faithful round-trip (emitting #[sea_orm(extra = "GENERATED ...")] and marking the field read-only) would be a larger, cross-crate change — table_xinfo does not return the generation expression — and is noted as a follow-up in #3094.


Authored by an AI agent (Claude Code, Anthropic), reviewed by a maintainer of a downstream project that hit this on a routine sea-orm-cli bump.

SQLite generated columns (`GENERATED ALWAYS AS (...) VIRTUAL`/`STORED`) became
discoverable when SQLite discovery switched to `PRAGMA table_xinfo`
(SeaQL/sea-schema#161, fixing schema-sync issue SeaQL#2995). As a side effect,
`sea-orm-cli generate entity` now reverse-generates them as ordinary, writable
entity fields. They are read-only at the storage layer, so they end up in the
derived `ActiveModel` and any `Model::into_active_model()` round-trip fails with
SQLite's "cannot INSERT/UPDATE a generated column".

Drop generated columns from the discovered table before it is written to an
entity. Discovery is left untouched, so schema sync keeps seeing the columns.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@JMLX42 JMLX42 marked this pull request as ready for review June 23, 2026 20:58
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.

sea-orm-cli generate entity emits SQL generated columns (VIRTUAL/STORED) as writable fields

1 participant