transform() now works for tables referenced by views - #832
Open
simonw wants to merge 3 commits into
Open
Conversation
Bracket the ALTER TABLE ... RENAME TO statements emitted by transform_sql() with PRAGMA legacy_alter_table=ON/OFF. Since SQLite 3.25 the rename would otherwise rewrite references in every view definition, which failed with "no such table" when a view referenced the just-dropped table, and with keep_table= silently repointed dependent views at the frozen backup table. View definitions are now left byte-for-byte unchanged by a transform. Closes #831 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #832 +/- ##
=======================================
Coverage 95.55% 95.55%
=======================================
Files 9 9
Lines 3800 3805 +5
=======================================
+ Hits 3631 3636 +5
Misses 169 169 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
transform_sql() now reads the connection's current PRAGMA legacy_alter_table value and emits a closing pragma that restores it, instead of always resetting it to OFF. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
simonw
commented
Aug 7, 2026
|
|
||
| A view that references a column which the transform renamed or dropped will remain defined but will raise a ``no such column`` error when it is next queried. This is inherent to SQLite views, whose SQL is stored as text - if you rename or drop columns that a view depends on you should update that view definition yourself. | ||
|
|
||
| To achieve this, the SQL produced by ``transform_sql()`` brackets its ``ALTER TABLE ... RENAME TO`` statements with ``PRAGMA legacy_alter_table=ON`` and ``PRAGMA legacy_alter_table=OFF`` - without this, SQLite would attempt to rewrite references to the renamed table in every view definition, which fails when a view references the table that was just dropped. One consequence is that ``PRAGMA legacy_alter_table`` is reset to ``OFF`` (the SQLite default) after a transform, even if it was previously set to ``ON`` for the connection. |
Owner
Author
There was a problem hiding this comment.
One consequence is that
PRAGMA legacy_alter_table is reset to OFF (the SQLite default) after a transform, even if it was previously set to ONfor the connection.
We can do better than that: spot what the previous value is at the start of the transform and set it back to that at the end.
The pragma does not exist there, so querying it returns no rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
|
Got a test failure against older SQLite 3.23.1 (prior to |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes:
Claude Fable 5 (Claude Code for web) PR
What changed
transform_sql()now brackets itsALTER TABLE ... RENAME TOstatements withPRAGMA legacy_alter_table=ON, followed by a closing pragma that restores the value the connection had when the SQL was generated (usuallyOFF, the SQLite default):In the
keep_table=variant the pragma brackets both renames.Why
Since SQLite 3.25,
ALTER TABLE ... RENAME TOvalidates and rewrites references to the renamed table in every view definition. This caused two bugs:error in view v: no such table: main.t, breaking every transform-based operation (retyping, renaming, dropping columns, changing primary keys, foreign key changes).keep_table=silently repointed views at the backup table - when the rename succeeded, SQLite rewrote dependent views to select from the frozen backup copy instead of the live table, with no error or warning.These renames are an internal implementation detail of
transform(), so view definitions should not be touched. The pragmas are emitted fromtransform_sql()rather than handled insidetransform(), so the documented "run these statements yourself" workflow andsqlite-utils transform --sqloutput remain standalone-correct.Resulting semantics
transform()with their SQL byte-for-byte unchanged, and keep reading from the live table even withkeep_table=.no such columnwhen next queried - inherent to SQLite views, whose SQL is stored as text.PRAGMA legacy_alter_tableis restored to the value it had before the transform, noted in the docs.Reviewer notes
tests/test_transform.pycovering view preservation across rename/retype/pk-change/FK-change transforms, the renamed-column caveat, a view-on-view chain, thekeep_tablerepointing regression, standalone execution oftransform_sql()output, and transform inside an already-open transaction. The 13 parametrized expected-SQL lists gained the two pragma lines. Full suite: 1403 passed, 16 skipped.docs/python-api.rst, cross-reference and updated--sqlexample indocs/cli.rst, changelog entry (in an "Unreleased" section - fold into the next release heading when cutting it).docs/changelog.rst(before the.. _v4_1:label) that broke strict Sphinx builds.🤖 Generated with Claude Code
📚 Documentation preview 📚: https://sqlite-utils--832.org.readthedocs.build/en/832/