Skip to content

AwaitRequired with sqlite+aiolibsql in SQLAlchemy 2.0 — DBAPI sync masked as async? #109

@swaggyd1

Description

@swaggyd1

Summary

When using create_async_engine("sqlite+aiolibsql:///...") from SQLAlchemy 2.0, every awaited operation raises AwaitRequired even with poolclass=StaticPool or NullPool explicitly set. The dialect sqlite.aiolibsql (registered by sqlalchemy-libsql) advertises async support, but the underlying DBAPI (libsql-experimental) appears to be sync internally — so the dialect's async claim is either false or requires an async-specific DBAPI package that is not published.

This makes sqlalchemy-libsql unusable as a drop-in replacement for aiosqlite in SQLAlchemy 2.0 async stacks.

Versions

  • Python 3.12
  • SQLAlchemy 2.0.49
  • alembic 1.18.4
  • sqlalchemy-libsql 0.2.0 (entry-points: sqlite.libsql, sqlite.aiolibsql)
  • libsql-experimental 0.0.55 (transitive)
  • Linux (WSL2 Ubuntu 22.04)

Minimal reproduction

import asyncio
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.pool import StaticPool
from sqlalchemy import text

async def main():
    engine = create_async_engine(
        "sqlite+aiolibsql:///:memory:",
        poolclass=StaticPool,
    )
    async with engine.connect() as conn:
        await conn.execute(text("SELECT 1"))

asyncio.run(main())

Result: AwaitRequired raised on await conn.execute(...).

Companion observations

  • The sibling dialect sqlite+libsql is rejected by create_async_engine with "The asyncio extension requires an async driver" — confirms it is sync, as expected.
  • On Windows native (Python 3.12), libsql-experimental==0.0.55 has no cp312-win-amd64 wheel and the sdist build fails on MAX_PATH=260 in the uv cache path during CMake/MSBuild — separate platform issue, not the focus here.

Expected behavior

Either:

  • sqlite+aiolibsql works as a true async dialect with a corresponding async DBAPI, or
  • the dialect is removed / clearly documented as not yet functional, with a tracking issue for the async DBAPI work.

Context

Filed while evaluating libsql as a drop-in for aiosqlite in a SQLAlchemy 2.0 async project. Decision documented in https://github.com/swaggyd1/trampo/blob/master/docs/decisions/0003-spike-libsql-swap.md (ADR-0003 outcome). Stayed on aiosqlite until the async path is functional. Happy to test patches.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions