uesleilima opened a new issue, #2369:
URL: https://github.com/apache/age/issues/2369

   **Is your feature request related to a problem?**
   
   The `Age` class and `Age.connect()` create and own a single 
`psycopg.Connection` internally. In production applications that need 
connection pooling (via `psycopg_pool.ConnectionPool` or similar), there is no 
supported way to:
   
   1. Register agtype adapters on externally-managed connections.
   2. Use a pool's `configure` callback to set up AGE on each new connection.
   3. Pass a pre-existing connection into the `Age` wrapper.
   4. Access `AgeLoader` and `ClientCursor` without reaching into private 
module attributes (`age.age.AgeLoader`, `age.age.ClientCursor`).
   
   The only option is to replicate the driver's internal setup logic manually, 
which is fragile and tightly coupled to implementation details.
   
   **Current workaround**
   
   ```python
   import age
   import psycopg
   from psycopg.types import TypeInfo
   from psycopg_pool import ConnectionPool
   
   def _configure_age_connection(conn):
       """Per-connection AGE setup — replicates driver internals."""
       with conn.cursor() as cur:
           cur.execute('SET search_path = ag_catalog, "$user", public;')
   
       ag_info = TypeInfo.fetch(conn, "agtype")
       if ag_info is None:
           raise RuntimeError("AGE agtype type not found")
   
       # These are private module attributes — no public API exists
       conn.adapters.register_loader(ag_info.oid, age.age.AgeLoader)       # 
type: ignore
       conn.adapters.register_loader(ag_info.array_oid, age.age.AgeLoader)  # 
type: ignore
       conn.commit()
   
   pool = ConnectionPool(
       conninfo="host=localhost dbname=mydb",
       configure=_configure_age_connection,
       kwargs={"cursor_factory": age.age.ClientCursor},  # type: ignore
   )
   pool.open()
   ```
   
   This works, but relies on `age.age.AgeLoader` and `age.age.ClientCursor` 
which are not part of any documented public API and require `# type: ignore` to 
satisfy type checkers.
   
   **Describe the solution you'd like**
   
   Expose a public function that configures an existing connection for AGE use, 
without creating a new connection or running `LOAD 'age'`:
   
   ```python
   # Proposed API
   def configure_connection(conn, graph_name=None, skip_load=False):
       """Register agtype adapters on an existing connection.
   
       Sets search_path, fetches agtype OIDs, and registers AgeLoader.
       Optionally checks/creates the graph.
   
       This enables use with external connection pools.
       """
       ...
   ```
   
   Additionally, export `AgeLoader` and `ClientCursor` as documented public 
symbols (e.g., via `__all__` in `__init__.py` or as top-level imports).
   
   **Describe alternatives you've considered**
   
   - Monkeypatching `Age.connect()` to accept an existing connection — fragile.
   - Subclassing `Age` to override connection creation — the class was not 
designed for inheritance.
   
   Related: #2353 (skip_load parameter) addresses part of this by making 
`setUpAge()` work on managed PostgreSQL, but even with that fix, there is no 
clean way to use the driver with a connection pool.
   
   **Environment**
   
   - Python driver: master branch (psycopg3 version)
   - psycopg: 3.2.x
   - psycopg_pool: 3.2.x


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to