Docs/Integrate/Async
OSS

Async

AsyncDBLiftClient runs DBLift from an asyncio application without blocking the event loop. It wraps the sync client and runs each operation in one dedicated worker thread.

api · AsyncDBLiftClient

Basic usage

run.py

python
from sqlalchemy import create_engine from dblift.api.async_client import AsyncDBLiftClient async def run(): engine = create_engine("postgresql+psycopg://user:pass@localhost/db") async with AsyncDBLiftClient.from_sqlalchemy( engine, migrations_dir="migrations" ) as client: await client.migrate() info = await client.info()

FastAPI startup guard

main.py

python
from contextlib import asynccontextmanager from fastapi import FastAPI from dblift.api.async_client import AsyncDBLiftClient from dblift.integrations.fastapi import migration_guard_async @asynccontextmanager async def lifespan(app: FastAPI): async with AsyncDBLiftClient.from_sqlalchemy( engine, migrations_dir="migrations" ) as client: await migration_guard_async(client, on_pending="raise") yield app = FastAPI(lifespan=lifespan)

Methods

Every operation has an awaitable mirror: migrate, info, validate, undo, generate_undo_script, generate_undo_scripts, clean, baseline, repair and import_flyway, plus aclose() and async with. The three constructors — from_sqlalchemy, from_config and from_config_file — stay synchronous because construction is cheap; only operations are awaited. A connection that cannot be opened, or a schema-history table that cannot be created, returns the same failed result as the synchronous client. The async client runs the synchronous methods in a worker thread. It does not raise.

What it is and is not

  • Single-flight per client. Operations on one client are serialized by an internal lock and run on the same worker thread, because the underlying connection is shared and not safe for concurrent use. For parallelism, use separate clients and engines.
  • Not native async database I/O. The call occupies a worker thread. This suits migrations that run at startup, not high-frequency per-request queries.
  • Cancellation is handled. A cancelled await does not abandon the worker mid-operation; the operation is allowed to finish before the cancellation surfaces.
  • Events pass straight through. client.events is the wrapped sync client’s emitter, so listeners — including the OpenTelemetry instrumentation — work unchanged.

One client, one connection

A closed client rejects further operations rather than reconnecting. Build a new client if you need one after aclose().

On this page