Skip to content

Docs: correct what transform() does to indexes, views and triggers - #854

Open
dchaudhari7177 wants to merge 1 commit into
simonw:mainfrom
dchaudhari7177:docs/849-transform-indexes-views-triggers
Open

Docs: correct what transform() does to indexes, views and triggers#854
dchaudhari7177 wants to merge 1 commit into
simonw:mainfrom
dchaudhari7177:docs/849-transform-indexes-views-triggers

Conversation

@dchaudhari7177

@dchaudhari7177 dchaudhari7177 commented Sep 6, 2026

Copy link
Copy Markdown

Closes #849.

The line under Custom transformations with .transform_sql() says .transform() "does not automatically upgrade indexes, views or triggers". All three parts are wrong — and the trigger one is wrong in the dangerous direction.

Measured on current main, across all three kinds of transform:

rename a column   triggers ['trg'] -> []   views kept   indexes kept
change a type     triggers ['trg'] -> []   views kept   indexes kept
drop a column     triggers ['trg'] -> []   views kept   indexes kept
  • Indexes are handled. transform_sql() captures each one before the old table is dropped and reissues its CREATE INDEX, rewriting a renamed column: CREATE INDEX "idx" ON "t" ("new_name").
  • Views are kept — and were already documented accurately under Tables referenced by views, so the old sentence also contradicted a section four paragraphs above it.
  • Triggers are dropped, not "not upgraded". SQLite deletes a table's triggers with the table, and transform_sql() never captures them.

That last one is why I'd treat this as more than a wording tidy. A reader told a trigger was not upgraded reasonably expects it to still exist, possibly stale. It is gone — silently, on every transform(), including one called with no arguments to reformat the schema.

What replaces it

A short Indexes and triggers section covering what actually happens, including two details I had to read transform_sql() to get right:

  • an index with no stored CREATE INDEX (one implied by a UNIQUE constraint) is not reissued, because the constraint is reproduced in the new CREATE TABLE instead — verified, UNIQUE survives;
  • any other index without stored SQL raises TransformError telling you to drop and recreate it yourself.

The trigger part carries a recipe using table.triggers_dict, with the caveat that a captured trigger body still names the old columns.

Verification

Everything asserted above was run against main before being written, including the recipe:

triggers_dict works:        ['trg']
after transform, triggers:  []
after reissue,   triggers:  ['trg']
index recreated on       :  CREATE INDEX "idx" ON "t" ("new_name")
UNIQUE kept in new schema:  True
sphinx-build -b html -W --keep-going docs    clean

The issue also suggested the views wording needed changing. I left the Tables referenced by views section alone — it is already precise, including the no such column case — and only removed the stale sentence that contradicted it.

Happy to split the trigger behaviour into its own issue if you'd rather transform() preserved them instead; this PR only documents what it does today.


📚 Documentation preview 📚: https://sqlite-utils--854.org.readthedocs.build/en/854/

The line under "Custom transformations with .transform_sql()" said
`.transform()` "does not automatically upgrade indexes, views or triggers".
All three parts are wrong, and the trigger one is wrong in the dangerous
direction. Measured on current main:

    rename a column   triggers ['trg'] -> []  views kept  indexes kept
    change a type     triggers ['trg'] -> []  views kept  indexes kept
    drop a column     triggers ['trg'] -> []  views kept  indexes kept

* Indexes *are* handled. `transform_sql()` captures each one before the old
  table is dropped and reissues its CREATE INDEX, rewriting a renamed
  column: `CREATE INDEX "idx" ON "t" ("new_name")`.
* Views are kept, and were already documented accurately under "Tables
  referenced by views" -- so the old sentence also contradicted a section
  four paragraphs above it.
* Triggers are not merely "not upgraded". They are **dropped**. SQLite
  deletes a table's triggers with the table, and `transform_sql()` never
  captures them. A reader told the trigger was not *upgraded* would expect
  it to still exist, possibly stale. It is gone.

Replaces the sentence with an "Indexes and triggers" section covering what
actually happens, including the `UNIQUE`-constraint index case (not
reissued, because the constraint is reproduced in the new CREATE TABLE) and
the TransformError raised for any other index without stored SQL.

The trigger part carries a recipe using `table.triggers_dict`, with the
caveat that a captured trigger body still names the old columns. Both the
recipe and every claim above were run against main before being written.

Docs build clean under `sphinx-build -W`.

Closes simonw#849
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.

Clarify transform() behavior for indexes, views and triggers

1 participant