Common Table Expressions (CTE) for Django
Project description
# Common Table Expressions (CTE) for Django
## 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.
```py
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`.
```py
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.
## Running tests
```
cd django-cte
mkvirtualenv cte # or however you choose to setup your environment
pip install nose flake8
nosetests
flake8
```
## 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.
```py
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`.
```py
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.
## Running tests
```
cd django-cte
mkvirtualenv cte # or however you choose to setup your environment
pip install nose flake8
nosetests
flake8
```
Project details
Release history Release notifications | RSS feed
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-0.1.tar.gz
(6.5 kB
view hashes)
Built Distribution
Close
Hashes for django_cte-0.1-py2.py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | eaf0ec4be3a507231e01d836836798bf65008b05ae21a607c41b55ecd87af78f |
|
MD5 | 1442a9078784d98857cae9c9a419b267 |
|
BLAKE2b-256 | be9772872baa4afe40ae840669c2901a48fb3b38d3d05d672c43d5911aae95da |