{"record":{"id":"7d6fbfbb6f077820","repo":"tursodatabase/turso","slug":"cannot-get-raw-connection-from-sqlalchemy-connecti","errorCode":null,"errorMessage":"Cannot get raw connection from SQLAlchemy connection","messagePattern":"Cannot get raw connection from SQLAlchemy connection","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"bindings/python/turso/sqlalchemy/dialect.py","lineNumber":527,"sourceCode":"            sync.push()\n\n    Args:\n        connection: A SQLAlchemy Connection object\n\n    Returns:\n        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":509,"sourceCodeEnd":539,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/python/turso/sqlalchemy/dialect.py#L509-L539","documentation":"get_sync_connection unwraps a SQLAlchemy Connection down to the raw DBAPI connection via getattr(connection, \"connection\"). If the passed object has no `connection` attribute, it cannot be a SQLAlchemy Connection and the helper raises TypeError(\"Cannot get raw connection from SQLAlchemy connection\") naming the misuse.","triggerScenarios":"Calling get_sync_connection(engine) (an Engine), get_sync_connection(session) (a Session), or get_sync_connection(raw_connection) (an already-raw ConnectionSync) — none expose the `.connection` attribute a live SQLAlchemy Connection has.","commonSituations":"Convenience wrappers that accept 'anything connection-ish'; passing session objects from ORM code; tests passing mocks or fakes that only partially imitate Connection.","solutions":["Pass a live Connection: `with engine.connect() as conn: sync = get_sync_connection(conn)`","From ORM code use the contextual connection: `get_sync_connection(session.connection())`","If you already hold a ConnectionSync, use it directly — no unwrapping needed"],"exampleFix":"# before\nengine = create_engine(\"sqlite+turso_sync:///local.db?remote_url=...\")\nsync_conn = get_sync_connection(engine)  # TypeError\n\n# after\nwith engine.connect() as conn:\n    sync_conn = get_sync_connection(conn)\n    rows = sync_conn.cursor().execute(\"SELECT 1\").fetchall()","handlingStrategy":"type-guard","validationCode":"from sqlalchemy.engine import Connection\n\ndef is_sa_connection(obj) -> bool:\n    \"\"\"True only for live SQLAlchemy Connection objects (what get_sync_connection needs).\"\"\"\n    return isinstance(obj, Connection)","typeGuard":"from sqlalchemy.engine import Connection, Engine\nfrom sqlalchemy.orm import Session\n\ndef accepts_get_sync_connection(obj) -> bool:\n    if isinstance(obj, (Engine, Session)):\n        return False  # common mistakes: pass a Connection instead\n    return hasattr(obj, \"connection\") and hasattr(obj, \"execute\")","tryCatchPattern":"try:\n    sync_conn = get_sync_connection(conn)\nexcept TypeError as e:\n    if \"Cannot get raw connection\" in str(e):\n        raise TypeError(\"pass a live SQLAlchemy Connection: with engine.connect() as c: ...\") from e\n    raise","preventionTips":["Always pass a Connection from `engine.connect()` or `session.connection()`","Engines, Sessions, and already-raw ConnectionSync objects are rejected — keep types straight at call sites","Type-annotate wrapper parameters as sqlalchemy.Connection so misuse fails static checks"],"tags":["python","sqlalchemy","api-misuse","types"],"backgroundTag":"wrong-argument-type","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}