Skip to main content

django-libsql-backend

PyPI version Python versions Django versions License: MIT

A drop-in Django database backend for libSQL and Turso. Supports remote Turso databases over HTTP/WebSocket and local SQLite files.

Use a local .sqlite3 file during development, then switch to a production Turso URL with zero code changes — same ENGINE, same ORM, same migrations.


Features

  • Triple-mode — auto-detects local file paths, remote HTTP URLs, or WebSocket (Hrana) from the NAME setting
  • Zero external dependencies — uses only Python's stdlib (urllib, json)
  • Full ORM support — querysets, aggregations, annotations, ON CONFLICT (upsert)
  • Migrations — makemigrations, migrate, sqlmigrate work out of the box
  • Admin & Auth — Django admin, password hashing, sessions, permissions
  • Batch API — executemany() uses Turso's /v1/batch endpoint for efficient bulk operations
  • SQLite-compatible — delegates to Django's built-in SQLite schema editor and introspection
  • Django 4.2+ — tested on 5.0, 5.1, and 6.0

Requirements

Dependency Minimum
Python 3.10+
Django 4.2+
Turso / libSQL SQLite 3.31+

Installation

pip install django-libsql-backend

For WebSocket/Hrana mode:

pip install django-libsql-backend[hrana]

Quick Start

1. Get a Turso database

turso db create my-django-app
turso db tokens create my-django-app

2. Configure Django

import os

DATABASES = {
    "default": {
        "ENGINE": "django_libsql",
        "NAME": os.environ["TURSO_DB_URL"],
        "AUTH_TOKEN": os.environ["TURSO_AUTH_TOKEN"],
        "OPTIONS": {
            "timeout": 30,
        },
    }
}

3. Run migrations

python manage.py migrate

Local development

Point NAME at a file path — no Turso account needed:

DATABASES = {
    "default": {
        "ENGINE": "django_libsql",
        "NAME": "dev.sqlite3",
    }
}

When ready to deploy, change NAME to your Turso URL and add AUTH_TOKEN. Zero code changes required.


Configuration Reference

Setting Required Default Description
ENGINE Yes — "django_libsql"
NAME Yes — Database URL, hostname, or local file path
AUTH_TOKEN Remote only "" Turso platform auth token (JWT)
OPTIONS.timeout No 30 HTTP request timeout in seconds
OPTIONS.transaction_mode No None SQLite transaction mode: "DEFERRED", "EXCLUSIVE", or "IMMEDIATE" (local only)
OPTIONS.init_command No "" SQL commands to run on connection (local only, semicolon-separated)

NAME value formats

Format Example Mode
Full HTTPS URL https://my-db-org.turso.io Remote (HTTP)
Bare hostname my-db-org.turso.io Remote (HTTP)
libsql:// URL libsql://my-db-org.turso.io Remote (HTTP, converted to HTTPS)
ws:///wss:// URL wss://my-db-org.turso.io Remote (Hrana/WebSocket)
Absolute path /var/data/db.sqlite3 Local
Relative path ./dev.db Local
In-memory :memory: Local

Note: libsql:// URLs are automatically converted to HTTPS for the Turso REST API. Use ws:// or wss:// explicitly for WebSocket/Hrana mode (requires pip install django-libsql-backend[hrana]).


Architecture

┌──────────┐      HTTP POST /v1/execute       ┌──────────────┐
│  Django   │ ───────────────────────────────► │  Turso /     │
│  ORM /    │      HTTP POST /v1/batch         │  libSQL      │
│  Migrations│ ◄─────────────────────────────── │  Server      │
└──────────┘       JSON (typed-value)           └──────────────┘

How it differs from Django's built-in SQLite backend

Django SQLite django-libsql (local) django-libsql (remote)
Transport File I/O File I/O HTTP REST API
Connection Persistent Persistent Stateless — each request = new connection
Transactions Real Real Buffered writes flushed as batch on commit
Savepoints Yes Yes Client-side buffer snapshots only
DDL rollback Yes Yes Not supported — each DDL auto-commits
PRAGMAs Persistent Persistent Reset every HTTP request

Internal module layout

django_libsql/
├── __init__.py       # Exports DatabaseWrapper, __version__
├── base.py           # DatabaseWrapper, TursoCursor, TursoHTTPConnection, HranaCursor
├── features.py       # SQLite-compatible feature flags
├── operations.py     # SQL generation (date/time, upsert, operators)
├── schema.py         # Proxy to Django's SQLite schema editor
├── introspection.py  # Proxy to Django's SQLite introspection
├── creation.py       # Test database create/destroy
├── client.py         # CLI: dbshell (turso or sqlite3)
└── functions.py      # Custom DB functions (local mode)

Known Limitations

These apply only to remote (Turso HTTP) mode. Local mode has full SQLite support.

Stateless HTTP connection

Each Turso HTTP request creates a new SQLite connection. PRAGMA settings do not persist between requests. DDL cannot be rolled back.

Transactions

Remote mode uses client-side write buffering for best-effort atomicity:

  • Writes inside atomic() blocks are buffered in memory
  • On commit, all buffered writes are flushed as a single batch
  • Reading inside a transaction auto-flushes buffered writes first (read-your-writes)
  • Accessing cursor.lastrowid also triggers a flush
  • Once flushed, writes cannot be rolled back

Unavailable SQL functions

These Django ORM functions use Python-registered SQL functions not available on remote servers:

  • Hash: MD5, SHA1, SHA224, SHA256, SHA384, SHA512
  • String: LPad, RPad, Repeat, Reverse
  • Math: Cot, Sign (rewritten automatically), BitXor (raises error)
  • Aggregate: StdDev, Variance

Timezone handling

SQLite has no native timezone support. Results are correct when the database stores UTC (Django's default).


Troubleshooting

"Turso HTTP 401"

Your auth token is invalid or expired. Generate a new one:

turso db tokens create <db-name>

"Turso connection error: timed out"

Increase the timeout:

"OPTIONS": {"timeout": 60}

"RuntimeError: No connection established"

Verify NAME and AUTH_TOKEN in your database settings.


Development

git clone https://github.com/CyberCalculus/django-libsql-backend.git
cd django-libsql-backend
pip install -e .
python manage.py check
python manage.py migrate

License

MIT. See LICENSE.


Metadata

Release files for django-libsql-backend 0.1.3

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-libsql-backend 0.1.3
File Size Uploaded Provenance
django_libsql_backend-0.1.3.tar.gz 30.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for django-libsql-backend 0.1.3
File Interpreter ABI Platform
django_libsql_backend-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 61.1 kB

Release files / django_libsql_backend-0.1.3.tar.gz

Download URL django_libsql_backend-0.1.3.tar.gz
Size 30.3 kB
Tags Source
SHA-256 checksum
How to use checksums
f29af92043f7b5831b40fa14fc3780da15ee39f8324e3f2ae5f549ef888e2c1a
BLAKE2b-256 checksum
How to use checksums
7d59326e9b409820643b8f7dabb06b09dd7cad93c805f734efe8f575288364ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 4, 2026.

Transparency log

Release files / django_libsql_backend-0.1.3-py3-none-any.whl

Download URL django_libsql_backend-0.1.3-py3-none-any.whl
Size 30.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
23acc6e31a4903228e57104fc856c6a25a753f28d483ae208bf8de4b66b27329
BLAKE2b-256 checksum
How to use checksums
60458ca52eb9ac2d3c537cba50f20f03d6e0ae2ba9c9010ca2c03d7b300883b2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 4, 2026.

Transparency log

Security for django-libsql-backend 0.1.3

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for django_libsql_backend-0.1.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 4, 2026.

Transparency log

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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