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]