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

Fixed #26709 -- Add class based indexes and CreateIndex operation #6726

Closed
wants to merge 1 commit into from

Conversation

akki
Copy link
Contributor

@akki akki commented Jun 5, 2016

Ticket #26709.

tablespace_sql = " " + tablespace_sql

if not hasattr(self, 'name'):
self.name = schema._create_index_name(self.model, columns, suffix=suffix)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure if this is the right place to do this. Please have a look.

Copy link
Member

Choose a reason for hiding this comment

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

I do think this would be an obvious extension point for a subclass. Perhaps get_name()?

Copy link
Contributor Author

@akki akki Jun 7, 2016

Choose a reason for hiding this comment

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

Should I write a new method get_name for Index class, which would create a name for the index independent of the schema. That way we will also have a uniform naming standard for the indexes, no matter which database the user uses.
But we might have to think about backward compatibility for this.

Copy link
Member

Choose a reason for hiding this comment

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

I think the name should be generated as part of the index class and should be database backend independent, otherwise your migrations would yield different names depending on the database used to generate the migrations.

@mjtamlyn
Copy link
Member

mjtamlyn commented Jun 6, 2016

I think this is broadly heading in the right direction. I'd like to see some example migration file code. Perhaps it's worth you setting up a simple project that we can build up the functionality but makes it easy to show that it works.

I think Index.as_sql is likely to need some refactoring as we make it more complex to support other options. In particular, I think that just using interpolation into schema.sql_create_index may prove too simplistic.

@timgraham
Copy link
Member

About naming, we have:
CreateModel, DeleteModel
AddField, RemoveField,

It would be nice if the new operations were consistent with these names. I guess I'd go with AddIndex/RemoveIndex since, like fields, these are ancillary things to models -- other opinions?


.. versionadded:: 1.11

Creates a new index in the database table for the given model. ``model_name`` is the model's name
Copy link
Member

Choose a reason for hiding this comment

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

please wrap documentation lines at 79 characters

@charettes
Copy link
Member

About naming, we have:
CreateModel, DeleteModel
AddField, RemoveField,

It would be nice if the new operations were consistent with these names. I guess I'd go with AddIndex/RemoveIndex since, like fields, these are ancillary things to models -- other opinions?

Agreed.

@MarkusH
Copy link
Member

MarkusH commented Jun 8, 2016

About naming, we have:
CreateModel, DeleteModel
AddField, RemoveField,

It would be nice if the new operations were consistent with these names. I guess I'd go with AddIndex/RemoveIndex since, like fields, these are ancillary things to models -- other opinions?

Agreed.

The names are derived from the SQL syntax which is CREATE INDEX and DROP INDEX. (CREATE TABLE / DROP TABLE, ADD COLUMN / DROP COLUMN [I agree the latter is poorly chosen]).

model_state = state.models[app_label, self.model_name.lower()]
if not hasattr(self.index, 'model'):
self.index.model = state.apps.get_model(app_label, self.model_name)
if 'indexes' not in model_state.options:
Copy link
Member

Choose a reason for hiding this comment

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

This should never be the case. ModelState should have a default indexes = []

@MarkusH
Copy link
Member

MarkusH commented Jun 8, 2016

About naming, we have:
CreateModel, DeleteModel
AddField, RemoveField,

It would be nice if the new operations were consistent with these names. I guess I'd go with AddIndex/RemoveIndex since, like fields, these are ancillary things to models -- other opinions?

Agreed.

The names are derived from the SQL syntax which is CREATE INDEX and DROP INDEX. (CREATE TABLE / DROP TABLE, ADD COLUMN / DROP COLUMN [I agree the latter is poorly chosen]).

Well there we go, I don't even recall the names of the operations: it's CreateModel/DeleteModel and AddField/RemoveField. Anyhow, I find CreateIndex/DeleteIndex more intuitive (the keyword for the creating a new index is still the same as in SQL)

@charettes
Copy link
Member

As indexes are related to a table/model I find AddIndex/RemoveIndex more appropriate.

Is there a reason not to use a single AlterIndexes operation analogous to AlterUniqueTogether/AlterIndexTogether?

@@ -17,4 +17,5 @@ Model API reference. For introductory material, see :doc:`/topics/db/models`.
lookups
expressions
conditional-expressions
indexes
Copy link
Member

Choose a reason for hiding this comment

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

I'd probably add this right after fields

@akki
Copy link
Contributor Author

akki commented Jun 19, 2016

I have updated the algorithm.
Two indexes are identical if they are on the same table, have the same set of fields and are of the same type, so I have taken all three of these into account while hashing.
Also, I have alloted a share to each of them in the index name to keep it meaningful (as much as possible). I have given more share to table-name than field-name because table-name contains both app label and model name which usually makes it significantly larger than the column name.

if index_name[0] == "_":
index_name = index_name[1:]
# It can't start with a number on Oracle, so prepend D if we need to
if index_name[0].isdigit():
Copy link
Member

Choose a reason for hiding this comment

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

Add validation that user-provided names don't start with a digit?

@timgraham
Copy link
Member

Some cosmetic edits at akki#2.

@akki
Copy link
Contributor Author

akki commented Jun 22, 2016

@timgraham Added tests for index names starting with numbers and underscores (regarding get_name) if that's what you meant.


def state_forwards(self, app_label, state):
model_state = state.models[app_label, self.model_name.lower()]
if not hasattr(self.index, 'model'):
Copy link
Member

Choose a reason for hiding this comment

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

I think this if statement can be removed as it doesn't seem to ever evaluate to False when running the test suite.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does for new Index instances.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops, I forgot the not. Done.

Added corresponding migration operations - AddIndex, RemoveIndex to use them

Thanks to markush, mjtamlyn, timgraham and charettes for reviewing and all the discussions.
@akki
Copy link
Contributor Author

akki commented Jun 27, 2016

Updated PR addressing all comments. Rebased against master and squashed all commits.

@timgraham
Copy link
Member

merged in 156e2d5, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants