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"))
}}}
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