An open API service indexing awesome lists of open source software.

https://github.com/imsweb/django-dbtasks

Database task backend and runner for Django tasks
https://github.com/imsweb/django-dbtasks

Last synced: 22 days ago
JSON representation

Database task backend and runner for Django tasks

Awesome Lists containing this project

README

          

# django-dbtasks

Database backend and runner for [Django tasks](https://docs.djangoproject.com/en/dev/topics/tasks/) (new in 6.0).

`django-dbtasks` is tested on PostgreSQL, SQLite, and MySQL for versions of Python back to 3.12, including the free-threading builds.

_Note when using SQLite it is recommended to set `OPTIONS["transaction_mode"] = "IMMEDIATE"` - see https://forum.djangoproject.com/t/sqlite-and-database-is-locked-error/26994 for more information._

## Quickstart

Install the `django-dbtasks` package from PyPI, and configure your [TASKS setting](https://docs.djangoproject.com/en/dev/ref/settings/#std-setting-TASKS) as follows:

```python
TASKS = {
"default": {
"BACKEND": "dbtasks.backend.DatabaseBackend",
"OPTIONS": {
# Set this to True to execute tasks immediately (no need for a runner).
"immediate": False,
# Whether to send `task_enqueued`, `task_started`, and `task_finished`.
"signals": True,
# How long to retain ScheduledTasks in the database. Forever if not set.
"retain": datetime.timedelta(days=7),
# Tasks to run periodically.
"periodic": {
# Runs at 3:30am every Monday through Friday.
"myproject.tasks.maintenance": "30 3 * * 1-5",
},
},
},
}
```

## Runner

`django-dbtasks` includes a dedicated `taskrunner` management command:

```
usage: manage.py taskrunner [-h] [-w WORKERS] [-i WORKER_ID] [--backend BACKEND]
[--delay DELAY] [--no-periodic]
```

It is also straightforward to run the runner in a thread of its own:

```python
runner = Runner(workers=4, worker_id="in-process")
t = threading.Thread(target=runner.run)
t.start()
...
runner.stop()
t.join()
```

`django-dbtasks` itself is tested on free-threading builds of Python 3.13 and 3.14, but compatibility will depend on your database driver and other packages.

## Periodic Tasks

As shown in the [quickstart](#quickstart), periodic tasks are specified as a mapping in the backend `OPTIONS` under the `periodic` key. The keys of the mapping should be dotted paths to the tasks, and the values should either be a string in [crontab format](https://crontab.guru), or an instance of `dbtasks.Periodic`. Using a `dbtasks.Periodic` allows you to specify `args` and `kwargs` (as values or callables) that will be passed to the task, along with a custom `retain` duration.

## Logging

Be sure to add a `dbtasks` logger to your `LOGGING` setting:

```python
LOGGING = {
...
"loggers": {
"dbtasks": {
"handlers": ["console"],
"level": "INFO",
},
},
}
```

## Testing

There is a `RunnerTestCase` that starts a runner for the duration of a test suite. See [test_tasks.py](tests/tests/test_tasks.py) for example usage.

## Extras

`django-dbtasks` comes with a number of optional features for integration into various environments.

### `dbtasks.contrib.serve`

This is a Django app you can add to `INSTALLED_APPS` to enable a `serve` management command that runs your site in a [Granian](https://github.com/emmett-framework/granian) server, with options to also start an integrated task runner. For instance, the following command will serve your site on `127.0.0.1:8000`, start a runner, and reload your server (and tasks!) on code changes:

```
manage.py serve -k -r
```

Running an integrated task runner (with `-k/--tasks`) is not a great idea in production, but is excellent for development. Granian is a production-caliber server, so you can also use `serve` in production alongside a separate [taskrunner command](#runner).

You can install the `django-dbtasks[serve]` extra to include Granian automatically.

### uWSGI mule

You can run a [uWSGI mule](https://uwsgi-docs.readthedocs.io/en/latest/Mules.html) that starts a task runner by passing `--mule=dbtasks.contrib.mule:taskrunner` or specifying `dbtasks.contrib.mule:taskrunner` in your XML config.