Skip to main content

Use Postgres' generate_series to create sequences with Django's ORM

Project description

django-generate-series

Use Postgres' generate_series to create sequences with Django's ORM

https://django-generate-series.readthedocs.io/

Goals

When using Postgres, the set-returning functions allow us to easily create sequences of numbers, dates, datetimes, etc. Unfortunately, this functionality is not currently available within the Django ORM.

This project makes it possible to create such sequences, which can then be used with Django QuerySets. For instance, assuming you have an Order model, you can create a set of sequential dates and then annotate each with the number of orders placed on that date. This will ensure you have no date gaps in the resulting QuerySet. To get the same effect without this package, additional post-processing of the QuerySet with Python would be required.

Terminology

Although this packages is named django-generate-series based on Postgres' generate_series set-returning function, mathematically we are creating a sequence rather than a series.

  • sequence: Formally, "a list of objects (or events) which have been ordered in a sequential fashion; such that each member either comes before, or after, every other member."

    In django-generate-series, we can generate sequences of integers, decimals, dates, datetimes, as well as the equivalent ranges of each of these types.

  • term: The nth item in the sequence, where 'nth' can be found using the id of the model instance.

    This is the name of the field in the model which contains the term value.

API

The package includes a generate_series function from which you can create your own series-generating QuerySets. The field type passed into the function as output_field determines the resulting type of series that can be created. (Thanks, @adamchainz for the format suggestion!)

generate_series arguments

  • start - The value at which the sequence should begin (required)
  • stop - The value at which the sequence should end. For range types, this is the lower value of the final term (required)
  • step - How many values to step from one term to the next. For range types, this is the step from the lower value of one term to the next. (required for non-integer types)
  • span - For range types other than date and datetime, this determines the span of the lower value of a term and its upper value (optional, defaults to 1 if neeeded in the query)
  • output_field - A django model field class, one of BigIntegerField, IntegerField, DecimalField, DateField, DateTimeField, BigIntegerRangeField, IntegerRangeField, DecimalRangeField, DateRangeField, or DateTimeRangeField. (required)
  • include_id - If set to True, an auto-incrementing id field will be added to the QuerySet.
  • max_digits - For decimal types, specifies the maximum digits
  • decimal_places - For decimal types, specifies the number of decimal places
  • default_bounds - In Django 4.1+, allows specifying bounds for list and tuple inputs. See Django docs

Basic Examples

# Create a bunch of sequential integers
integer_sequence_queryset = generate_series(
    0, 1000, output_field=models.IntegerField,
)

for item in integer_sequence_queryset:
    print(item.term)

Result:

term
----
0
1
2
3
4
5
6
7
8
9
10
...
1000
# Create a sequence of dates from now until a year from now
now = timezone.now().date()
later = (now + timezone.timedelta(days=365))

date_sequence_queryset = generate_series(
    now, later, "1 days", output_field=models.DateField,
)

for item in date_sequence_queryset:
    print(item.term)

Result:

term
----
2022-04-27
2022-04-28
2022-04-29
2022-04-30
2022-05-01
2022-05-02
2022-05-03
...
2023-04-27

Note: See the docs and the example project in the tests directory for further examples of usage.

Usage with partial

If you often need sequences of a given field type or with certain args, you can use partial.

Example with default include_id and output_field values:

from functools import partial

int_and_id_series = partial(generate_series, include_id=True, output_field=BigIntegerField)

qs = int_and_id_series(1, 100)

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_generate_series-0.5.0.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

django_generate_series-0.5.0-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file django_generate_series-0.5.0.tar.gz.

File metadata

  • Download URL: django_generate_series-0.5.0.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.2.2 CPython/3.10.6 Linux/5.15.0-56-generic

File hashes

Hashes for django_generate_series-0.5.0.tar.gz
Algorithm Hash digest
SHA256 8cced6473ba75aed5e1e2ecd6f5426d11d33926e86d2630dabe9c424b7a6da8a
MD5 7dd47ebb1d56ff29cbb2fe9bf317b9f2
BLAKE2b-256 d35248f0d808f22742e91f13f36292709b070bd4ee5948db80b5ef8489c31164

See more details on using hashes here.

File details

Details for the file django_generate_series-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for django_generate_series-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 54e33e5aba69be75f591bda970421dee9f1c5feeb84c20d8cee634bcc0e249bc
MD5 256c206220fe67b5ea37ac7ee6a137b1
BLAKE2b-256 7fa6e046d514139eec2b0d534a499a5bee5eb735e45b528113bf5cd7cdf87a2d

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