{"record":{"id":"38de0a7cdcea1a14","repo":"tursodatabase/turso","slug":"expected-turso-sync-connectionsync-got-type-dbap","errorCode":null,"errorMessage":"Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__name__}. This function only works with sqlite+turso_sync:// connections.","messagePattern":"Expected turso\\.sync\\.ConnectionSync, got (.+?)\\. This function only works with sqlite\\+turso_sync:// connections\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"bindings/python/turso/sqlalchemy/dialect.py","lineNumber":533,"sourceCode":"        The underlying turso.sync.ConnectionSync object\n\n    Raises:\n        TypeError: If the connection is not a Turso sync connection\n    \"\"\"\n    from turso.lib_sync import ConnectionSync\n\n    # Get the raw DBAPI connection\n    # SQLAlchemy 2.0: connection.connection.dbapi_connection\n    # SQLAlchemy 1.4: connection.connection\n    raw_conn = getattr(connection, \"connection\", None)\n    if raw_conn is None:\n        raise TypeError(\"Cannot get raw connection from SQLAlchemy connection\")\n\n    # Handle SQLAlchemy 2.0 pooled connection wrapper\n    dbapi_conn = getattr(raw_conn, \"dbapi_connection\", raw_conn)\n\n    if not isinstance(dbapi_conn, ConnectionSync):\n        raise TypeError(\n            f\"Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__name__}. \"\n            \"This function only works with sqlite+turso_sync:// connections.\"\n        )\n\n    return dbapi_conn\n","sourceCodeStart":515,"sourceCodeEnd":539,"githubUrl":"https://github.com/tursodatabase/turso/blob/244cde92a7df7f9b8b8b7a4075c35a12977e303e/bindings/python/turso/sqlalchemy/dialect.py#L515-L539","documentation":"After unwrapping, get_sync_connection checks isinstance(dbapi_conn, ConnectionSync). Anything else - a pysqlite connection, an async-dialect connection, a plain object - raises TypeError naming the actual type. The helper only works with connections created by the sqlite+turso_sync:// dialect, because only that dialect builds ConnectionSync instances underneath SQLAlchemy.","triggerScenarios":"Passing a Connection from the async dialect (sqlite+turso:// used with an async engine) or from SQLAlchemy's built-in sqlite dialect; passing a ConnectionSync created by hand instead of through the dialect.","commonSituations":"An app with both sync and async engines where the wrong connection object reaches the helper; refactors that switch dialect entry points; tests using in-memory pysqlite for speed.","solutions":["Create the engine with the sqlite+turso_sync:// dialect for connections you will unwrap","For async engines, use the async access path instead of this sync helper","Branch on engine.dialect.name or the connection type before calling the helper"],"exampleFix":"# before\nengine = create_engine(\"sqlite+turso:///:memory:\")  # async-style dialect\nwith engine.connect() as conn:\n    raw = get_sync_connection(conn)  # TypeError\n\n# after\nengine = create_engine(\"sqlite+turso_sync:///:memory:\")\nwith engine.connect() as conn:\n    raw = get_sync_connection(conn)","handlingStrategy":"type-guard","validationCode":"from turso.lib_sync import ConnectionSync\n\ndef unwrap_sync_connection(conn):\n    dbapi = getattr(getattr(conn, \"connection\", None), \"dbapi_connection\", None)\n    return dbapi if isinstance(dbapi, ConnectionSync) else None","typeGuard":"from turso.lib_sync import ConnectionSync\n\ndef is_turso_sync_sa_connection(conn) -> bool:\n    dbapi = getattr(getattr(conn, \"connection\", None), \"dbapi_connection\", None)\n    return isinstance(dbapi, ConnectionSync)","tryCatchPattern":"try:\n    raw = get_sync_connection(conn)\nexcept TypeError as e:\n    if \"turso.sync.ConnectionSync\" in str(e):\n        raise TypeError(\"Create the engine with sqlite+turso_sync:// URLs\") from e\n    raise","preventionTips":["Use sqlite+turso_sync:// for engines whose connections you will unwrap","Check engine.url.drivername before passing connections to dialect-specific helpers","Keep sync and async access paths in separate, clearly named functions"],"tags":["python","sqlalchemy","type-error","dialect"],"backgroundTag":"invalid-connection-type","analyzedSha":"244cde92a7df7f9b8b8b7a4075c35a12977e303e","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}