Opened 9 years ago
Last modified 3 years ago
#28053 assigned New feature
Allow fields to specify arbitrary indexes via db_index=Index()
| Reported by: | Marc Tamlyn | Owned by: | Aman Pandey | 
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev | 
| Severity: | Normal | Keywords: | indexes migrations | 
| Cc: | Markus Holtermann | Triage Stage: | Accepted | 
| Has patch: | yes | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | yes | 
| Easy pickings: | no | UI/UX: | no | 
Description
Expand Field.db_index to allow explicitly setting an index.
Syntax would look something like:
HStoreField(db_index=GinIndex())
Changes needed:
- Indexes won't necessarily receive fields initially.
 - Fields are responsible for their own indexes. This is tackled here and has implications for #27859, 
_likeindexes on Postgres, and other situations where we customise the indexes. It is possible, but I'm not sure, thatField.get_indexes()could also handle unique conditions, but I think it's better kept separately as not all databases consider uniqueness to be an index. - Change to 
SchemaEditor.alter_fieldso it receives theto_model, so that theIndexcan resolve the correct column names. This is extra important fordb_indexbeing a functional index (see #26167), although that's not currently supported in the current data. 
Change History (9)
comment:1 by , 9 years ago
| Needs documentation: | set | 
|---|---|
| Needs tests: | set | 
| Triage Stage: | Unreviewed → Accepted | 
comment:2 by , 9 years ago
| Type: | Uncategorized → New feature | 
|---|
comment:3 by , 7 years ago
| Owner: | changed from to | 
|---|---|
| Patch needs improvement: | unset | 
| Status: | new → assigned | 
new WP PR
comment:4 by , 7 years ago
| Version: | 1.11 → master | 
|---|
comment:5 by , 6 years ago
| Needs documentation: | unset | 
|---|---|
| Needs tests: | unset | 
comment:6 by , 6 years ago
| Patch needs improvement: | set | 
|---|
comment:7 by , 6 years ago
I had a chat with felixxm discussing the usefulness of this feature.
The initial idea behind this feature, as far as I can reconstruct from memory, came from the requirement that I wanted to have a custom index on a field by default, because I didn't want to tell users to add a specific index to Meta.indexes. The naïve approach Marc and I agreed upon back in the days was about this:
- A field has a 
default_index_classordefault_indexproperty/attribute or whatnot. When a field hasdb_index=True, this index definition would be used. - Now, a custom field that would want to require an index, could reject 
db_indexas an argument in__init__and set it toTrueall the time. - A user could, however, may would like to be able to make adjustments to the index that's defined by the field. Thus, passing their own index definition in place of 
db_index(and not have the field reject the argument. 
This change would also allow to dynamically construct an index based on the other arguments passed to __ini__:
class MyField(CharField): def __init__(self, arg1: str, arg2: int, **kwargs): db_index = kwargs.pop("db_index", None) if db_index is None: db_index = MyIndexClass(arg1, math.pi * arg2) super().__init__(db_index=db_index, **kwargs) class MyModel(models.Model): field1 = MyField() field2 = MyField(db_index=Index(name="foo"))
The key, I believe, is that the implementation of default_index_class or default_index or however the API might look like, would be a prerequisite for this ticket.
comment:8 by , 6 years ago
Hi, thanks for your detailed explanation. Firstly, I wanted to be sure to understand you. Because of that I've issued a commit. I'm using _get_index_type_kwargs to getting kwargs for _create_index_sql. I applied it in this part. what do you think?
comment:9 by , 3 years ago
| Owner: | changed from to | 
|---|
WIP PR