Skip to main content

Subclass of django.db.models.Index, which enables indexing on expressions.

Project description

django-expression-index

PyPI

django-expression-index provides implementation of subclass of django.db.models.Index, which enables indexing tables using expressions.

In Django 3.2 this solution is obsoleted by built-in support of expression index.

What problem does this solve?

Currently django.db.models.Index only accepts field names in fields parameter. There is no way to add expression index other than using raw SQL.

This project implements ExpressionIndex class, which accepts list of any django.db.models.expressions.Expression in its expressions parameter.

How to use it?

Here is an example of adding index based on lowercased models.CharField value.

from django.db import models
from django.db.models.functions import Lower
from django_expression_index import ExpressionIndex

class Profile(models.Model):
    name = models.CharField(max_length=255)

    class Meta:
        indexes = [
            ExpressionIndex(expressions=[Lower('name')])
        ]

After adding ExpressionIndex to your indexes, run makemigrations and migrate commands. The following SQL code will be generated and executed on your database:

CREATE TABLE "myapp_profile" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(255) NOT NULL);
CREATE INDEX "myapp_profile_9a3539_idx" ON "myapp_profile" (LOWER("name"));

ExpressionIndex constructor replaces fields parameter with expressions parameter. All remaining parameters are relayed to django.db.models.Index constructor.

How does it work?

ExpressionIndex overrides create_sql method and uses django's default query compiler to render the expression.

There is a monkey-patch implemented on django.db.models.sql.query.Query instance, which replaces resolve_ref. The patch forces using SimpleCol instead of Col class to render bare field names referred by the expression, without prefixing them with table name.

    def compile_expression(self, expression, compiler):
        def resolve_ref(original, name, allow_joins=True, reuse=None, summarize=False, simple_col=False):
            return original(name, allow_joins, reuse, summarize, True)

        query=compiler.query
        query.resolve_ref=partial(resolve_ref, query.resolve_ref)
        expression=expression.resolve_expression(query, allow_joins=False)
        sql, params=expression.as_sql(compiler, compiler.connection)
        return sql % params

If you know a better solution, please let me know!

Compatibility

It was tested with Django 2.2.13 and 3.x. In release 0.2.1 code was updated to make it compatible with Django 3.2

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-expression-index-0.2.1.tar.gz (4.3 kB view details)

Uploaded Source

Built Distribution

django_expression_index-0.2.1-py3-none-any.whl (4.9 kB view details)

Uploaded Python 3

File details

Details for the file django-expression-index-0.2.1.tar.gz.

File metadata

  • Download URL: django-expression-index-0.2.1.tar.gz
  • Upload date:
  • Size: 4.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.5

File hashes

Hashes for django-expression-index-0.2.1.tar.gz
Algorithm Hash digest
SHA256 1e3edada6b6857b14996e89255e37ebe8879279d9a215be6ef720523c98d67b9
MD5 991bef63b062d67f32a25413c056d289
BLAKE2b-256 3242159c375864f21223c7e5df0bd30e8ad762973b2b642c21024257fb07dc75

See more details on using hashes here.

File details

Details for the file django_expression_index-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: django_expression_index-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 4.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/4.6.0 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.61.1 CPython/3.9.5

File hashes

Hashes for django_expression_index-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 db6e8ca5b95082f24052bcafd715def6d8ff227b00207105a101fd7d05f6fc54
MD5 42729f751bd3c63eb7341577ff911bfc
BLAKE2b-256 b42f355cd036ca93ce4143518261122019c3eef239ccc872549c42ea4af0d42c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page