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

add support for creating and deleting indexes #125

Merged
merged 3 commits into from
Oct 9, 2024

Conversation

timgraham
Copy link
Collaborator

refs #104

@timgraham timgraham marked this pull request as draft September 12, 2024 02:13
@timgraham timgraham changed the title add partial support for creating indexes and unique constraints add support for creating and deleting indexes Sep 13, 2024
@timgraham timgraham marked this pull request as ready for review September 13, 2024 01:53
@timgraham timgraham requested review from WaVEV and removed request for WaVEV September 13, 2024 01:53
@timgraham timgraham marked this pull request as draft September 13, 2024 14:57
@timgraham timgraham marked this pull request as ready for review September 16, 2024 14:53
@timgraham timgraham marked this pull request as draft September 17, 2024 15:01
@timgraham timgraham force-pushed the add-indexes branch 2 times, most recently from a0653e3 to 8520d2c Compare September 18, 2024 12:53
@timgraham timgraham marked this pull request as ready for review September 18, 2024 12:56
@timgraham timgraham marked this pull request as draft September 19, 2024 14:32
@timgraham timgraham marked this pull request as draft September 19, 2024 14:32
@timgraham timgraham marked this pull request as draft September 19, 2024 14:32
@timgraham timgraham force-pushed the add-indexes branch 5 times, most recently from 2e3cbc3 to 4b0172c Compare September 30, 2024 12:23
@timgraham timgraham marked this pull request as ready for review October 1, 2024 17:16
@timgraham timgraham requested review from Jibola and WaVEV October 3, 2024 16:45
def table_names(self, cursor=None, include_views=False):
return sorted([x["name"] for x in self.connection.database.list_collections()])

def get_constraints(self, cursor, table_name):
indexes = self.connection.database[table_name].index_information()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we use self.connection.get_collection instead of .database[table_name]. But I don't know if we have to keep get_collection.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, I'll rebase this after #152 and incorporate those changes.

Copy link
Collaborator

@Jibola Jibola left a comment

Choose a reason for hiding this comment

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

LGTM. Some comments getting clarity around constraints, but that's it.

Comment on lines +29 to +43
# Meta.index_together (RemovedInDjango51Warning)
for field_names in model._meta.index_together:
self._add_composed_index(model, field_names)
Copy link
Collaborator

Choose a reason for hiding this comment

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

For users of Django 5.1, the below for loop should include the index_together elements, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Support for Meta.index_together is removed in Django 5.1, so these lines will be removed.

Copy link
Collaborator

@Jibola Jibola Oct 9, 2024

Choose a reason for hiding this comment

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

Ahhh, looked over the documentation and see that this was deprecated since 4.2

Comment on lines +79 to +92
self._remove_field_index(model, old_field)
self._add_field_index(model, new_field)
Copy link
Collaborator

Choose a reason for hiding this comment

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

NIT: Add then remove. A dropped index has no further use, but adding one may need to be used quickly.

Copy link
Collaborator Author

@timgraham timgraham Oct 8, 2024

Choose a reason for hiding this comment

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

Is the scenario you imagine zero-downtime migrations? In that case, I think the developer would be advised to roll out schema changes in advance of the application logic that uses those fields, and thus we shouldn't worry about this sort of optimization.

Otherwise, a site should be in maintenance mode while deploying a new version that requires schema changes.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ahhh, okay. That was the exact case I had been thinking of.

Thought of it as a small optimization but if that's not standard practice I'm fine leaving it as is.

Comment on lines +116 to +129
if index.contains_expressions:
return
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should we not raise a NotSupportedError or what's the tactic for handling indexes with expressions. UUIC these are complex types that exist beyond the standard ASC/DESC indexing capabilities of MongoDB.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

They are ignored (in case the index is useful on another database backend) as per https://docs.djangoproject.com/en/dev/ref/models/indexes/#django.db.models.Index.expressions.

if index.contains_expressions:
return
index_orders = (
[(field.column, 1)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

NIT: Could we have 1 and -1 refer to a constant like in introspection.py?

The code here checks out. I think it just assists with readability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure. It's pymongo.ASCENDING / DESCENDING.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yep. Those are the best enums to use.

[(field.column, 1)]
if field
else [
(model._meta.get_field(field_name).column, 1 if order == "" else -1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's safe to assume this will either be an empty string or "-1"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Comment on lines 172 to 196
collection = self.connection.database[model._meta.db_table]
meta_index_names = {index.name for index in model._meta.indexes}
index_names = self._constraint_names(
model,
[field.column],
index=True,
# Retrieve only BTREE indexes since this is what's created with
# db_index=True.
type_=Index.suffix,
exclude=meta_index_names,
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we need to use index_names. Is it because there will be special prefixes attached to the naming on django-based indexes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The index name contains model._meta.db_table and if that changes after the index was created, the index isn't regenerated with a new name.

@timgraham timgraham merged commit 1c0706b into mongodb-labs:main Oct 9, 2024
4 checks passed
@timgraham timgraham deleted the add-indexes branch October 9, 2024 17:17
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.

3 participants