#33607: `PostgresIndex` uses `suffix` for both index name and method
------------------------------------------------+------------------------
Reporter: Alexandru Mărășteanu | Owner: (none)
Type: Bug | Status: new
Component: contrib.postgres | Version: dev
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
------------------------------------------------+------------------------
`django.contrib.postgres.indexes.PostgresIndex` uses the `suffix`
attribute for both generating the index name (in
`Index.set_name_with_model` see
https://github.com/django/django/blob/fac662f4798f7e4e0ed9be6b4fb4a87a80810a68/django/db/models/indexes.py#L153-L186)
and for deciding the indexing method (in `PostgresIndex.create_sql` i.e.
`CREATE INDEX ... USING {suffix} ...` see
https://github.com/django/django/blob/fac662f4798f7e4e0ed9be6b4fb4a87a80810a68/django/contrib/postgres/indexes.py#L25-L36).
A developer using and extending `PostgresIndex` for use with multiple
opclasses is unable to specify a custom suffix for the naming scheme.
For example, given two custom indexes like:
{{{
class Foo(GinIndex):
def __init__(self, *args, **kwargs):
super().__init__(*args, opclasses=[some opclass], **kwargs)
class Bar(GinIndex):
def __init__(self, *args, **kwargs):
super().__init__(*args, opclasses=[some opclass], **kwargs)
}}}
If set on the same model fields, both `Foo.set_name_with_model` and
`Bar.set_name_with_model` would then generate the same index name à la
`dbtable_field_hash_gin` which is not ok because index names need to be
unique.
Setting custom `suffix`es on `Foo` and `Bar` is not possible with the
current code because `PostgresIndex.create_sql` uses the suffix as the
index method. If the suffix doesn't match any of the supported opclasses,
then PostgreSQL complains about it.
To workaround that, an option would be to override the `create_sql`
method:
{{{
class Foo(GinIndex):
suffix = "foo"
def __init__(self, *args, **kwargs):
super().__init__(*args, opclasses=[some opclass], **kwargs)
def create_sql(self, model, schema_editor, using="", **kwargs):
return super().create_sql(model, schema_editor, using="gin",
**kwargs)
class Bar(GinIndex):
suffix = "bar"
def __init__(self, *args, **kwargs):
super().__init__(*args, opclasses=[some opclass], **kwargs)
def create_sql(self, model, schema_editor, using="", **kwargs):
return super().create_sql(model, schema_editor, using="gin",
**kwargs)
}}}
The problem is, even though `PostgresIndex.create_sql` accepts a `using`
argument, it currently ignores it. From the source code:
{{{
class PostgresIndex(Index):
...
def create_sql(self, model, schema_editor, using="", **kwargs):
...
statement = super().create_sql(
model, schema_editor, using=" USING %s" % self.suffix,
**kwargs
)
...
}}}
So in the end there's no way to extend the `PostgresIndex` with a custom
suffix. I was able to do it by temporarily setting a custom suffix in
`set_name_with_model` but that's more of a hack rather than a solution.
--
That said, I believe there are two things which need to be addressed here:
1. Distinguish between the index name suffix and the index method
`PostgresIndex` would then declare another property which indicated the
method to use when defining the index i.e. `using`.
2. `PostgresIndex.create_sql` respects the `using` argument
E.g. (also considering point 1 above):
{{{
class PostgresIndex(Index):
...
def create_sql(self, model, schema_editor, using="", **kwargs):
...
statement = super().create_sql(
model, schema_editor, using=using or self.using, **kwargs
)
...
}}}
---
If this is accepted, I'm available to work on it.
--
Ticket URL: <https://code.djangoproject.com/ticket/33607>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107017fda59ca92-ccaa43e2-3dfa-4b0c-b4a3-c84d8083c7e5-000000%40eu-central-1.amazonses.com.