-
Notifications
You must be signed in to change notification settings - Fork 6
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
Conversation
3c25544
to
fa74fae
Compare
fa74fae
to
945f7c8
Compare
a0653e3
to
8520d2c
Compare
2e3cbc3
to
4b0172c
Compare
django_mongodb/introspection.py
Outdated
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() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
# Meta.index_together (RemovedInDjango51Warning) | ||
for field_names in model._meta.index_together: | ||
self._add_composed_index(model, field_names) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
self._remove_field_index(model, old_field) | ||
self._add_field_index(model, new_field) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
if index.contains_expressions: | ||
return |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
django_mongodb/schema.py
Outdated
if index.contains_expressions: | ||
return | ||
index_orders = ( | ||
[(field.column, 1)] |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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.
django_mongodb/schema.py
Outdated
[(field.column, 1)] | ||
if field | ||
else [ | ||
(model._meta.get_field(field_name).column, 1 if order == "" else -1) |
There was a problem hiding this comment.
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"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
""
or "DESC"
as per https://github.com/django/django/blob/22e21ec641c6c533d31bef0db876c53207d14920/django/db/models/indexes.py#L66. I'll add a comment.
django_mongodb/schema.py
Outdated
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, | ||
) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
And also creating indexes in create_model() and add_field(), and removing them in remove_field().
refs #104