Opened 4 years ago
Last modified 7 days ago
#32770 assigned Cleanup/optimization
Add system check for django.contrib.postgres in INSTALLED_APPS when using the fields, indexes, and constraints it provides.
Description ¶
Given the following model + index:
from django.db import models from django.contrib.postgres.indexes import GinIndex, OpClass from django.db.models.functions import Cast class MyModel(models.Model): class Meta: indexes = [ GinIndex(OpClass(Cast("id", output_field=models.TextField()), name='gin_trgm_ops'), name='foobar') ]
After running makemigrations and running the migration, it produces the SQL:
CREATE INDEX "foobar" ON "myapp_mymodel" USING gin ((CAST("id" AS text) gin_trgm_ops));
Which is a syntax error on Postgres (version 12). The reason is the extra parentheses around CAST.
According to the ticket's flags, the next step(s) to move this issue forward are:
- To provide a patch by sending a pull request. Claim the ticket when you start working so that someone else doesn't duplicate effort. Before sending a pull request, review your work against the patch review checklist. Check the "Has patch" flag on the ticket after sending a pull request and include a link to the pull request in the ticket comment when making that update. The usual format is:
[https://github.com/django/django/pull/#### PR]
.
Change History (11)
comment:1 by , 4 years ago
Cc: | added |
---|---|
Component: | Migrations → Database layer (models, ORM) |
Easy pickings: | unset |
Resolution: | → worksforme |
Status: | new → closed |
comment:2 by , 4 years ago
I'm pretty sure that you're seeing this error because of not adding django.contrib.postgres
to INSTALLED_APPS
, see: https://docs.djangoproject.com/en/3.2/ref/contrib/postgres/indexes/#opclass-expressions
comment:3 by , 4 years ago
Resolution: | worksforme |
---|---|
Status: | closed → new |
Summary: | GinIndex with OpClass and Cast results in Postgres syntax error in migration → GinIndex with OpClass and Cast results in Postgres syntax error in migration when django.contrib.postgres is not part of INSTALLED_APPS |
Mariusz Felisiak, thanks for your comment. If you'll see my example, the extra parentheses are surrounding gin_trgm_ops
as well, not just the CAST
expression. This seems to be the problem.
Thank you Hannes Ljungberg!
I did not notice that the documentation says to add django.contrib.postgres
to INSTALLED_APPS
. That fixes the problem.
Would it be an idea to make a check that django.contrib.postgres
is in INSTALLED_APPS
when making use of OpClass
so that instead of encountering a Postgres syntax error and not knowing what to do (and assuming there is a bug in Django), you would get a helpful error message telling how to correct the problem?
Therefore I'm reopening the issue, and hoping that this check can be made, as despite this requirement being mentioned in the docs, the current behavior is quite unintuitive.
comment:4 by , 4 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
Summary: | GinIndex with OpClass and Cast results in Postgres syntax error in migration when django.contrib.postgres is not part of INSTALLED_APPS → Add system check for django.contrib.postgres in INSTALLED_APPS when using OpClass(). |
Type: | Bug → New feature |
Therefore I'm reopening the issue, and hoping that this check can be made, as despite this requirement being mentioned in the docs, the current behavior is quite unintuitive.
It would be really complicated. First of all, we would need to mix-up logic from a contrib app and the ORM. Secondly OpClass()
don't need to be the topmost expression, so the flatten list of expression would be necessary. Thirdly we don't have similar checks for fields from django.contrib.postgres
app which also require including 'django.contrib.postgres'
in INSTALLED_APPS
, e.g. HStoreField
. I don't think it's worth complexity, however we can reconsider this decision if someone provides PoC.
comment:5 by , 11 months ago
Cc: | added |
---|
In the light of continuous reports of users running into this qwirk (#35431 being the latest one) I wonder if we could
- Have all fields defined in
contrib.postgres
have theircheck
method make sure that'django.contrib.postgres' in INSTALLED_APPS
- Adjust
Model._check_indexes
to do something similar to what we did withConstraint
check delegation in 0fb104dda287431f5ab74532e45e8471e22b58c8 - Have both
contrib.postgres
indexes and constraints perform the same'django.contrib.postgres' in INSTALLED_APPS
check
Thoughts?
comment:6 by , 9 days ago
I'd like to re-iterate my plea for the above to take place. I helped another user who ran into the same issue today and it was far from clear what exactly was to blame.
Now that 2. from comment:5 is accepted under #36273 would there be interest in re-opening this ticket?
comment:7 by , 8 days ago
Hello, "user who ran into this same issue" here, I am in favor of A. reopening this issue, and B. adding this check so it is clear what needs to be done, instead of chasing my tail for a day and a half.
Thanks!
comment:8 by , 8 days ago
Component: | Database layer (models, ORM) → contrib.postgres |
---|---|
Resolution: | needsinfo |
Status: | closed → new |
Version: | 3.2 → dev |
It seems feasible now that Simon outlined a plan.
comment:9 by , 7 days ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:10 by , 7 days ago
Summary: | Add system check for django.contrib.postgres in INSTALLED_APPS when using OpClass(). → Add system check for django.contrib.postgres in INSTALLED_APPS when using the fields, indexes, and constraints it provides. |
---|---|
Triage Stage: | Unreviewed → Accepted |
Type: | New feature → Cleanup/optimization |
Clifford note that this ticket won't be completable until #36273 is completed as the check that should be added django.contrib.postgres.PostgresIndex
requires that check
method be exposed to subclasses to avoid coupling core with contrib.
comment:11 by , 7 days ago
Thanks Simon👍. I noticed, and cc'd myself in #36273 so as to stay up-to-date with the goings-on there.
Extra parentheses shouldn't be an issue on PostgreSQL. Also I cannot reproduce this crash on PostgreSQL 12.6, see the following test.