Skip to main content

kajenn-db

Database handlers for kajenn: the implementations of kajenn's DbHandlerBase contract, one module per backend.

  • kajenn_db.asqueel.AsqueelDbHandler — asqueel 0.9.
  • kajenn_db.sqlalchemy.SqlAlchemyDbHandler — SQLAlchemy 2, a probe.
  • kajenn_db.django.DjangoDbHandler — Django, a probe.

The probes are incomplete by declaration: they run kajenn's handler contract on another backend and stop there (see Probes).

Install

pip install kajenn-db[asqueel]
pip install kajenn-db[sqlalchemy]
pip install kajenn-db[django]

Importing a backend module without its extra raises an ImportError that names the command above.

Declare an asqueel database

from kajenn import AsgiServer
from kajenn.config import AsgiConfigBuilder
from kajenn_db.asqueel import AsqueelDbHandler


class Configuration(AsgiConfigBuilder):
    default_config = False

    def main(self, root):
        cfg = root.configuration()
        dbs = cfg.databases(handler_class=AsqueelDbHandler)
        dbs.database(code="default", source="shop.xml")

Each database accepts:

  • source — anything AsqueelDb(source, parents=...) accepts: a recipe, a registered name, a file, a db node.
  • parents — passed to AsqueelDb as it is.
  • db_class — an AsqueelDb subclass to build instead of AsqueelDb.

The server builds one AsqueelDbHandler and hands it every database declared with it. No database is opened at declaration time.

One session per call

  • request.db(name) takes the main SessionDb of the call (db.session()), once per name per call.
  • At the end of the call the handler closes the named sessions of the call, then the main one. Work not committed is rolled back, and asqueel logs a warning.
  • In 0.1.0 a session opens with no environment: currentUser is None, and workdate and locale take asqueel's defaults.

Async routes

An async def route takes request.async_db(name): the async view of the same main SessionDb. Its I/O methods are awaitable and run on the server pool, so the event loop keeps serving other calls.

@route()
async def add(self, _request=None):
    db = _request.async_db()
    notes = db.table("app.note")
    await notes.insert({"id": "n1", "text": "first"})
    await db.commit()
    return await notes.query(columns="$id").fetchPkeys()

The view has three levels, plus the cursor:

  • session — awaitable: execute, executemany, commit, rollback, vacuum, analyze. table(name) and session(name) return views.
  • table — awaitable: insert, update, delete, insertOrUpdate, lock. query(...) returns a view.
  • query — awaitable: fetch, fetchRecord, fetchPkeys, fetchAsJson, fetchAsDict, fetchAsBag, fetchGrouped, count, delete, update, execute, cursor.
  • cursor — returned by execute and cursor; awaitable: fetchone, fetchmany, fetchall, close.

Every other I/O method raises UnsupportedFeatureError on the view, naming what to use instead: iterfetch and serverfetch name cursor(); close belongs to the end of the call; migrate and migration_plan belong to the handler. Methods that do no I/O pass through as asqueel has them.

Rules:

  • In an async route, never call a SessionDb method on request.db(): it runs on the event loop and blocks every other call, with no error.
  • Consume a cursor before the call ends: the end of the call closes the session, and the cursor with it.
  • A streaming response that reads a cursor registers the release after its last chunk.
  • query(...).fetch() loads every row in memory. For large results, read a server-side cursor (cursorname) in chunks.

Serialising rows

kajenn serialises a dict/list result with genro_tytx.json_dumps (genro-tytx 0.16.4). Rows returned as asqueel gives them do not survive it:

  • a row of fetch() or fetchAsDict() (NamedList) becomes a bare list of values: the column names are lost;
  • date, datetime, Decimal and UUID values raise TypeError.

Convert in the route: dict(row.items()) keeps the column names, and the values of those four types need converting too. fetchAsJson() returns the JSON text itself: kajenn serves a str result as text/plain. The handler converts nothing, so a query gives the same types in a sync and in an async route.

Probes

SQLAlchemy

from kajenn_db.sqlalchemy import SqlAlchemyDbHandler

dbs = cfg.databases(handler_class=SqlAlchemyDbHandler)
dbs.database(code="default", url="sqlite:///shop.sqlite")
  • url — the SQLAlchemy database URL; one shared Engine per database, disposed at server shutdown.
  • request.db(name) takes a Session of the call; the end of the call closes it, and a closed Session refuses any further use.
  • request.async_db(name) is kajenn's AsyncDbView over the same Session, so one call has one transaction in a sync and in an async route. Awaitable: execute, scalars, scalar, get, get_one, merge, flush, refresh, commit, rollback. Every other attribute passes through as it is, I/O included: query() and its Query.all(), delete(), connection() and begin() run on the event loop and block it, with no error. Unlike the asqueel view, the probe refuses nothing.
  • A Result reads its rows from the cursor when it is iterated, on the event loop: keep the results of an async route small.
  • No migrate: SQLAlchemy has no migration of its own (Alembic is a separate tool).

Django

from kajenn_db.django import DjangoDbHandler

dbs = cfg.databases(handler_class=DjangoDbHandler)
dbs.database(code="default", alias="default")
  • Django is configured by the process (DJANGO_SETTINGS_MODULE or settings.configure(), then django.setup()), not by the handler.
  • alias — a key of Django's DATABASES; the database's own name by default.
  • request.db(name) takes connections[alias], the connection Django's ORM uses on the calling thread: the ORM in a sync route works on it. The end of the call closes it on the same thread.
  • Sync routes only. Django binds a connection to the thread that opened it, and kajenn takes a database of an async def route on the event-loop thread: request.async_db(name) raises NotImplementedError. An async route uses Django's async ORM, whose connections kajenn does not release.
  • Not for sync work outside a route either: a task, a kbus call or a WSX message takes the connection on one pool thread, and kajenn releases it with server.run_sync, possibly on another. Django refuses to close it there (DatabaseError, logged by kajenn) and the connection stays open on the thread that opened it.
  • migration_plan(name) lists the migrations not yet applied, as app_label.name; migrate(name) applies them (manage.py migrate --database alias). Both are sync and close the calling thread's connection at the end.

Metadata

Release files for kajenn-db 0.1.0

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

Source distribution (sdist)

Source distribution for kajenn-db 0.1.0
File Size Uploaded Provenance Actions
kajenn_db-0.1.0.tar.gz 24.0 kB With provenance Details for kajenn_db-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for kajenn-db 0.1.0
File Interpreter ABI Platform Actions
kajenn_db-0.1.0-py3-none-any.whl Python 3 none any Details for kajenn_db-0.1.0-py3-none-any.whl

Total release size: 39.5 kB

Release files / kajenn_db-0.1.0.tar.gz

Download URL kajenn_db-0.1.0.tar.gz
Size 24.0 kB
Tags Source
SHA-256 checksum
How to use checksums
68b4fb8289e574f993d5a58a4fe6b582ca4cba74ab159e4ef891eb41c52ab1dd
BLAKE2b-256 checksum
How to use checksums
3dc066e366bdf617b64f084bedeaac75993535cad6503e1e7c61d097edb278ac
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 27, 2026.

Transparency log

Release files / kajenn_db-0.1.0-py3-none-any.whl

Download URL kajenn_db-0.1.0-py3-none-any.whl
Size 15.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
909cd5caae563faabe21986d404f22c276f61898670f5c46a19d7b16860de9de
BLAKE2b-256 checksum
How to use checksums
17eb97d8ae41a90a6d1c0216d7e2e4b6d70ce419573ce944b0caa267dc84818a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 27, 2026.

Transparency log

Security for kajenn-db 0.1.0

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 kajenn_db-0.1.0.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 Oct 27, 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.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full 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