mirror of
https://github.com/simonw/sqlite-utils.git
synced 2026-09-07 17:14:09 +02:00
Docs: correct what transform() does to indexes, views and triggers
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 #849
This commit is contained in:
parent
85b1be10c8
commit
7b840e0f45
1 changed files with 21 additions and 3 deletions
|
|
@ -2026,14 +2026,32 @@ A view that references a column which the transform renamed or dropped will rema
|
|||
|
||||
To achieve this, the SQL produced by ``transform_sql()`` turns on ``PRAGMA legacy_alter_table`` for its ``ALTER TABLE ... RENAME TO`` statements, then restores the pragma to the value it had when the SQL was generated - 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.
|
||||
|
||||
.. _python_api_transform_indexes_triggers:
|
||||
|
||||
Indexes and triggers
|
||||
--------------------
|
||||
|
||||
Indexes on the transformed table are recreated. ``transform_sql()`` captures each index before the old table is dropped and reissues its ``CREATE INDEX`` afterwards, so an index survives the transformation. An index on a renamed column is recreated against the new name, and an index on a dropped column is dropped with it.
|
||||
|
||||
An index that SQLite does not expose a ``CREATE INDEX`` statement for - one created implicitly by a ``UNIQUE`` constraint - is not reissued. ``UNIQUE`` constraints are reproduced in the new ``CREATE TABLE`` instead, so the constraint is kept. Any other index without stored SQL raises ``TransformError`` asking you to drop and recreate it yourself.
|
||||
|
||||
**Triggers on the transformed table are dropped, not recreated.** SQLite deletes a table's triggers when the table is dropped, and ``transform_sql()`` does not capture them, so any trigger on the table is gone after the transformation. Read them from ``table.triggers_dict`` first if you need to recreate them:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
triggers = table.triggers_dict
|
||||
table.transform(rename={"old_name": "new_name"})
|
||||
for sql in triggers.values():
|
||||
db.execute(sql)
|
||||
|
||||
Note that a captured trigger body still references the old column names, so a trigger that mentions a renamed or dropped column needs editing before it is reissued.
|
||||
|
||||
.. _python_api_transform_sql:
|
||||
|
||||
Custom transformations with .transform_sql()
|
||||
--------------------------------------------
|
||||
|
||||
The ``.transform()`` method can handle most cases, but it does not automatically upgrade indexes, views or triggers associated with the table that is being transformed.
|
||||
|
||||
If you want to do something more advanced, you can call the ``table.transform_sql(...)`` method with the same arguments that you would have passed to ``table.transform(...)``.
|
||||
The ``.transform()`` method can handle most cases. If you want to do something more advanced - reissuing triggers, or adding statements of your own - you can call the ``table.transform_sql(...)`` method with the same arguments that you would have passed to ``table.transform(...)``.
|
||||
|
||||
This method will return a list of SQL statements that should be executed to implement the change. You can then make modifications to that SQL - or add additional SQL statements - before executing it yourself.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue