Skip to main content

Helpers for using Django from threads

When handling requests django manages database connection lifecycles for you. By default closing them after each request or keeping them alive allowing re-use for a specified amount of time when CONN_MAX_AGE is set so long as no errors are encountered.

Sometimes you want to do work outside of a web request. When the work is large and you would like to distribute it, likely to places other than where the web requests are served, there are systems like Celery. There are other cases though were you're just trying to do work outside of the request & response cycle even and it's lightweight enough that running a full-blown job queuing system and it's associated data store is too involved. You just want Threads or even better a ThreadPoolExecutor.

If you just jump straight in and use either of those you'll run into slow to manifest and tough to track down problems with broken database connections. This is because Django automatically opens a connection per-thread when a database is accessed and leaves them lying around in that thread indefinitely. This results in errors when the database has timed out the connection or it has otherwise encountered problems.

django_thread provides a this problem by implementing a Thread class that mimics Django's request connection handling and provides a ThreadPoolExecutor that does so around the invocations of submitted calls.

Usage

Thread

django_thread.Thread is a 100% drop-in replacement for threading.Thread. See threading.Thread for usage and documentation.

from django_thread import Thread


class ExampleThread(Thread):
    def run(self):
        for some_model in SomeModel.objects.filter(...):
            ...


thread = ExampleThread()
thread.start()
# do other things
thread.join()

ThreadPoolExecutor

django_thread.ThreadPoolExecutor is a 100% drop-in replacement for concurrent.futures.ThreadPoolExecutor. See concurrent.futures.ThreadPoolExecutor for usage and documentation.

from concurrent.futures import as_completed
from django_thread import ThreadPoolExecutor


def update_or_create_thing(name):
    thing, _ = Thing.objects.update_or_create(name=name)
    return thing.id


executor = ThreadPoolExecutor()

futures = []
for i in range(5):
    future = executor.submit(update_or_create_thing, f'Name i')
    futures.append(future)

ids = [f.result() for f in futures]

Metadata

Release files for django-thread 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-thread 0.0.1
File Size Uploaded Provenance
django_thread-0.0.1.tar.gz 3.6 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for django-thread 0.0.1
File Interpreter ABI Platform
django_thread-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 7.4 kB

Release files / django_thread-0.0.1.tar.gz

Download URL django_thread-0.0.1.tar.gz
Size 3.6 kB
Tags Source
SHA-256 checksum
How to use checksums
276cc21f3b2d747f63999b0910609b3ec5371e019844441b561a5c064a6c52d7
BLAKE2b-256 checksum
How to use checksums
4e04ee873a76f166f39fdae65d29e638ef222ad07c19205740bc97f7cff23c25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

Release files / django_thread-0.0.1-py3-none-any.whl

Download URL django_thread-0.0.1-py3-none-any.whl
Size 3.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a65398ded5cc99bb5a09cd4d32befef26662882e7993d5409e7824b82c0947f7
BLAKE2b-256 checksum
How to use checksums
db41643983d77b407259ef6e141f6e7bf7147acb0122884cb2ef5b9211602167
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.4.2 importlib_metadata/4.8.1 pkginfo/1.7.1 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.7

Security for django-thread 0.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page