Skip to main content

Common Table Expressions (CTE) for Django

Project description

Common Table Expressions (CTE) for Django

Build Status PyPI version

Installation

pip install django-cte

Usage

Simple Common Table Expressions

Simple CTE queries can be constructed using With. A custom CTEManager is used to add the CTE to the final query.

from django_cte import CTEManager, With

class Order(Model):
    objects = CTEManager()
    id = AutoField(primary_key=True)
    region = ForeignKey("Region", on_delete=CASCADE)
    amount = IntegerField(default=0)


cte = With(
    Order.objects
    .values("region_id")
    .annotate(total=Sum("amount"))
)

orders = (
    cte.join(Order, region=cte.col.region_id)
    .with_cte(cte)
    .annotate(region_total=cte.col.total)
    .order_by("amount")
)

Orders returned by this query will have a region_total attribute containing the sum of all order amounts in the order's region.

Recursive Common Table Expressions

Recursive CTE queries can be constructed using With.recursive.

class Region(Model):
    objects = CTEManager()
    name = TextField(primary_key=True)
    parent = ForeignKey("self", null=True, on_delete=CASCADE)

def make_regions_cte(cte):
    return Region.objects.filter(
        # start with root nodes
        parent__isnull=True
    ).values(
        "name",
        path=F("name"),
        depth=Value(0, output_field=IntegerField()),
    ).union(
        # recursive union: get descendants
        cte.join(Region, parent=cte.col.name).values(
            "name",
            path=Concat(
                cte.col.path, Value("\x01"), F("name"),
                output_field=TextField(),
            ),
            depth=cte.col.depth + Value(1, output_field=IntegerField()),
        ),
        all=True,
    )

cte = With.recursive(make_regions_cte)

regions = (
    cte.join(Region, name=cte.col.name)
    .with_cte(cte)
    .annotate(
        path=cte.col.path,
        depth=cte.col.depth,
    )
    .order_by("path")
)

Regions returned by this query will have path and depth attributes. The results will be ordered by path (hierarchically by region name). In this case path is a '\x01'-delimited string of region names starting with the root region.

See tests for more advanced examples.

Running tests

cd django-cte
mkvirtualenv cte  # or however you choose to setup your environment
pip install django nose flake8

nosetests
flake8 --config=setup.cfg

Uploading to PyPI

Package and upload the generated files.

pip install -r pkg-requires.txt

python setup.py sdist bdist_wheel
twine upload dist/*

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-cte-1.1.2.tar.gz (7.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_cte-1.1.2-py2.py3-none-any.whl (8.7 kB view details)

Uploaded Python 2Python 3

File details

Details for the file django-cte-1.1.2.tar.gz.

File metadata

  • Download URL: django-cte-1.1.2.tar.gz
  • Upload date:
  • Size: 7.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for django-cte-1.1.2.tar.gz
Algorithm Hash digest
SHA256 bc9e8e4f3c0e8af8a0721f6cebeb0e1d62b4fe71ebde6257378f18681dd506ae
MD5 64160c4e4cbb30a52fc88815fe65d548
BLAKE2b-256 68f7c1cda8d0d8bb9161b1d0d76a7159242953dcc09be521364bc4af0759e51e

See more details on using hashes here.

File details

Details for the file django_cte-1.1.2-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_cte-1.1.2-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 f83f1cb7c9ee78341195cca1fbcd2a870f622812938662a598de1c1a72a43317
MD5 2c4d1d50ee61866e599f3530d7d14fc8
BLAKE2b-256 c65a4dfe98064e25f6b478c8e344e2e89b49755c4bcb9670a3e81fd8bc6d44e7

See more details on using hashes here.

Supported by

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