Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recreate indexes when calling transform when possible and raise an er… #634

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

matdmiller
Copy link

@matdmiller matdmiller commented Jul 21, 2024

Recreate indexes when calling transform when possible and raise an error when they cannot be retained automatically.

This resolves my initial problem: 'After creating a table with an index, if you add a foreign key constraint to the table it drops existing non-related indexes.'

GH Issue:

My explanation, thoughts and reasoning:

I think it is best to try and preserve existing indexes and fail loudly if they are unable to be recreated automatically. At the very least I believe you should be warned if they are not going to be recreated.

Below is my proposed solution with code:

  1. If a table is kept it will automatically drop the original index. To be able to create the index on the new table using the original CREATE INDEX statement the original index must be dropped. I think it's a reasonable default for the 'kept' table to lose its indexes. I suspect the most common reason to keep the original table is for 'backup' purposes. It would also be difficult to automatically create updated CREATE INDEX statements for the kept renamed table where the statements are more complicated.

  2. If a column exists in the original index but not in the new table, you should have to manually recreate the index as desired. In complicated CREATE INDEX statements it is difficult to automatically replace or remove columns correctly. Failing before any operations have been completed is desired because it allows you to know there will be a problem prior to the SQL statements being executed allowing you to collect the required information required to manually update the indexes prior to any actions taking place as well as not leaving your database in a potentially invalid state.


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

…ror when they cannot be retained automatically
"""SELECT sql FROM sqlite_master WHERE type = 'index' AND name = :index_name;""",
{"index_name": index.name},
).fetchall()[0][0]
assert index_sql is not None, (
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with assert for this kind of thing is that these won't execute if Python is run in optimize mode: https://docs.python.org/3/using/cmdline.html#cmdoption-O

I don't personally like that feature, but I think we should switch to a different exception just in case.

@@ -1967,6 +1967,28 @@ def transform_sql(
sqls.append(
"ALTER TABLE [{}] RENAME TO [{}];".format(new_table_name, self.name)
)
# Re-add existing indexes
for index in self.indexes:
if index.origin not in ("pk"):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this to 'index.origin != "pk"` instead.

@simonw
Copy link
Owner

simonw commented Nov 9, 2024

I tried running this through OpenAI's o1-preview as an experiment, specifically asking if the tests covered all of the cases: https://gist.github.com/simonw/edcd047a703ab6d6759a5a207364d744#response

It cost me $1.50 for the two prompts! Still reviewing the o1 produced test code to see if I think it's worth including.

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.

2 participants