cockroachdb / django-cockroachdb

CockroachDB Backend for Django
http://cockroachlabs.com
Apache License 2.0
160 stars 28 forks source link

Missing support trigram indexes / index opclasses #287

Open us2-robot opened 9 months ago

us2-robot commented 9 months ago

Hi, given the release of trigram indexes, I have tried to implement them in my django app. However, the migrations are failing. From what I can tell, django-cockroachdb hasn't been updated to support them yet (as seen here)

The output from python manage.py sqlmigrate confirms this:

When using engine django_cockroachdb, output shows CREATE INDEX "study_firstName" ON "study_study" USING gist ("firstName");

When using engine django.db.backends.postgresql, output shows CREATE INDEX "study_firstName" ON "study_study" USING gist ("firstName" gist_trgm_ops);

timgraham commented 9 months ago

Thanks for this. contrib.postgres isn't currently supported but perhaps we can work toward the goal of supporting the bits of that package that CockroachDB does support. Alternatively, or in addition, we might create a contrib.cockroach type package that includes the bits of contrib.postgres that CockroachDB supports, and perhaps some other things e.g. HashShardedIndex.

As for this issue, there are two possible ways to create the index:

  1. GistIndex(fields=["question_text"], opclasses=["gist_trgm_ops"], name='my-gist-index')

This requires changes to SchemaEditor._index_columns() as you linked to.

  1. GistIndex(OpClass(F("question_text"), name="gist_trgm_ops"), name='my-gist-index'),

This requires OpClass to be registered as an IndexExpression wrapper, otherwise the resulting SQL will have an extra set of parentheses, e.g. gist (("firstName" gist_trgm_ops)), which is invalid syntax.

us2-robot commented 9 months ago

I'm not familiar enough with Django internals & contribs to work out a proper solution but I've managed to make it work through the first way, i.e. monkey-patching _index_columns back to postgres's.

from django_cockroachdb.schema import DatabaseSchemaEditor
from django.db.backends.postgresql.schema import (DatabaseSchemaEditor as PostgresDatabaseSchemaEditor)
DatabaseSchemaEditor._index_columns = PostgresDatabaseSchemaEditor._index_columns

This wouldn't check against unsupported opclasses though, but is fine for my case :)