MagicStack / asyncpg

A fast PostgreSQL Database Client Library for Python/asyncio.
Apache License 2.0
6.99k stars 404 forks source link

Add connect kwarg to Pool to better support GCP's CloudSQL #1170

Closed d1manson closed 3 weeks ago

d1manson commented 3 months ago

This relates to an issue I created a few months back and then updated last week.

GCP's cloud-sql-python-connector offers asyncpg as one of its drivers - see logic here - however that can only be used as a single connection, not in conjunction with asyncpg's Pool class because it wraps the connection.connect(..) call in various bits of logic to do with authentication and SSL (which I admit I haven't tried to fully understand).

This PR simply turns the call to connection.connect into a kwarg parameter on the Pool class so it can be overridden.

Usage would be something like this:

from asyncpg import create_pool
from google.cloud.sql.connector import Connector

async def connect(dsn, **kwargs):
    # The dsn should be a cloudsql instance_connection_string, not a full dsn; we use the name 'dsn' for consistency
    # with the original asyncpg.connect function arguments.
    connector = Connector(enable_iam_auth=True) 
    return await connector.connect_async(
        dsn,
        driver="asyncpg",
        user="SOME_USER_HERE",
        **kwargs
    )

async def main():
    pool = create_pool(..., connect=connect)   # UPDATED: in an earlier version of this pr, this read connect_fn=connect
    ... 

Note the gcp repo's docs suggest using SQLAlchemy for a pool, but that's not much use if your codebase already uses asyncpg's Pool API (at least as far as I understand from SQLAlchemy).

--

Couple of additional thoughts:

  1. It is perhaps a bit confusing that there will now be three functions that all see somewhat similar in name - init, setup and a connect_fn, but I don't know enough to say if they can be refactored into fewer kwargs somehow.

  2. As noted in my issue, linked above, it is possible to work around this by subclassing the Pool class, but that's not especially nice and this seemed like a small ask so thought it was worth suggesting.