#19441 closed Bug (fixed)
No Postgres _like index when unique=True
Reported by: | Dylan Verheul | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | postgresql |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
class Species(models.Model): scientific_name = models.CharField(max_length=200, db_index=True)
Generates 2 indexes:
BEGIN; CREATE INDEX "species_species_scientific_name" ON "species_species" ("scientific_name"); CREATE INDEX "species_species_scientific_name_like" ON "species_species" ("scientific_name" varchar_pattern_ops); COMMIT;
class Species(models.Model): scientific_name = models.CharField(max_length=200, unique=True, db_index=True)
...does not create any indexes, because it depends on UNIQUE, but it SHOULD generate the index:
CREATE INDEX "species_species_scientific_name_like" ON "species_species" ("scientific_name" varchar_pattern_ops);
to make sure Postgres is optimized for LIKE operator.
Attachments (2)
Change History (16)
comment:1 by , 12 years ago
Description: | modified (diff) |
---|
comment:2 by , 12 years ago
Keywords: | postgresql added |
---|---|
Triage Stage: | Unreviewed → Accepted |
Version: | 1.5-beta-1 → master |
by , 12 years ago
Attachment: | 19441-1.diff added |
---|
comment:3 by , 12 years ago
Has patch: | set |
---|
comment:4 by , 12 years ago
comment:5 by , 12 years ago
Reporter: | changed from | to
---|
comment:6 by , 12 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
It seems that getting the LIKE index when db_index = True for unique field is correct.
I tested the patch on top of 1.5 for the indexes tests. This looks ready for commit to me.
comment:7 by , 12 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:9 by , 12 years ago
Now that I;'ve worked with this solution in 1.5c1 I am wondering if this is 100% correct.
For all systems except for postgres, unique=True makes db_index=True obsolete
For postgres, you would basically need to add db_index=True to fields with unique=True if you intend to do LIKE searches on that field.
So the choice is:
A - different technical behavior varying by db vendor (db_index is considered True if unique is True)
B - different functional behavior varying by db vendor (currently implemented behavior)
My knowledge of Django philosophy on these matters is too limited to take a good stance on this, so consider this just an extra heads up. Either way this might need some extra documentation. If you don't know where to look, this is a nasty one to find in Postgres country.
by , 12 years ago
Attachment: | 19441-2.diff added |
---|
comment:10 by , 12 years ago
Dylan, can you check the attached patch? Does it address your concerns?
The alternative would be to document that Postgres users who want to make like
queries on unique
fields should set db_index=True
in addition to unique=True
.
comment:11 by , 12 years ago
Claude, this would be perfect. The explanation you added (unique=True implies db_index=True on all occasions) says it all, and it very elegant.
The only "added weight" you collect by solving it like this is the creation of like-indexes on postgresql when the field is used as a unique identifier and not meant for like searching, The like indexes would be created but never used. I think this is not a problem, as it is far more important to have a unified way that Django works (again, unique=True implies db_index=True) than to take different database vendors into account when deciding when or not to add db_index=True.
To put it briefly, I'd be in favor of submitting this patch as the final solution for this issue.
Apologies if this is too much of a vanity request, but could this ticket's reporter be set to my user (dyve) instead of to my e-mail? Makes it easier to keep track of. Apparently I wasn't logged in properly when I filed it.