tursodatabase/turso · error · TypeError

Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__

Error message

Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__name__}. This function only works with sqlite+turso_sync:// connections.

What it means

After successfully unwrapping a SQLAlchemy Connection, get_sync_connection requires the underlying DBAPI connection to be a turso.lib_sync.ConnectionSync. Engines created with plain sqlite:// (pysqlite), sqlite+turso:// (non-sync dialect), or any other driver produce a different type, and the TypeError names the actual type and states that only sqlite+turso_sync:// connections work.

Source

Thrown at bindings/python/turso/sqlalchemy/dialect.py:533

        The underlying turso.sync.ConnectionSync object

    Raises:
        TypeError: If the connection is not a Turso sync connection
    """
    from turso.lib_sync import ConnectionSync

    # Get the raw DBAPI connection
    # SQLAlchemy 2.0: connection.connection.dbapi_connection
    # SQLAlchemy 1.4: connection.connection
    raw_conn = getattr(connection, "connection", None)
    if raw_conn is None:
        raise TypeError("Cannot get raw connection from SQLAlchemy connection")

    # Handle SQLAlchemy 2.0 pooled connection wrapper
    dbapi_conn = getattr(raw_conn, "dbapi_connection", raw_conn)

    if not isinstance(dbapi_conn, ConnectionSync):
        raise TypeError(
            f"Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__name__}. "
            "This function only works with sqlite+turso_sync:// connections."
        )

    return dbapi_conn

View on GitHub (pinned to bad083fafb)

Solutions

  1. Create the engine with the sync dialect: `create_engine("sqlite+turso_sync:///local.db?remote_url=libsql://...&auth_token=...")`
  2. Check the engine.url.drivername is 'turso_sync' before calling sync-specific helpers
  3. Keep one canonical URL constant used by both app and migrations so the dialect stays consistent

Example fix

# before
engine = create_engine("sqlite:///local.db")
with engine.connect() as conn:
    sync_conn = get_sync_connection(conn)  # TypeError: expected ConnectionSync

# after
engine = create_engine("sqlite+turso_sync:///local.db?remote_url=libsql://db.example.com")
with engine.connect() as conn:
    sync_conn = get_sync_connection(conn)
Defensive patterns

Strategy: type-guard

Validate before calling

from sqlalchemy import create_engine

engine = create_engine("sqlite+turso_sync:///local.db?remote_url=libsql://db.example.com")
assert engine.url.drivername == "turso_sync", "sync helpers need the turso_sync driver"

Type guard

from sqlalchemy.engine import Connection
from turso.lib_sync import ConnectionSync

def is_sync_connection(conn: Connection) -> bool:
    """True when the SQLAlchemy Connection wraps a turso sync DBAPI connection."""
    raw = getattr(conn, "connection", None)
    dbapi = getattr(raw, "dbapi_connection", raw)
    return isinstance(dbapi, ConnectionSync)

Try / catch

try:
    sync_conn = get_sync_connection(conn)
except TypeError as e:
    if "only works with sqlite+turso_sync" in str(e):
        engine = create_engine("sqlite+turso_sync:///local.db?remote_url=...")
        with engine.connect() as c2:
            sync_conn = get_sync_connection(c2)
    else:
        raise

Prevention

When it happens

Trigger: create_engine("sqlite:///local.db") with pysqlite and passing its Connection to get_sync_connection; using the non-sync turso dialect (sqlite+turso://) and expecting sync features; a URL whose driver name fell back to another dialect.

Common situations: Projects that started on plain sqlite and added turso sync later without changing the URL; copy-paste dialect URLs; alembic env.py configured with sqlite:// while sync code expects ConnectionSync.

Related errors


AI-assisted analysis of tursodatabase/turso@bad083fafb (2026-08-16). Data as JSON: /api/errors/38de0a7cdcea1a14. Report an issue: GitHub.