Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cleanup aiopg.pool.Pool.cursor method #264

Open
thehesiod opened this issue Jan 26, 2017 · 2 comments · May be fixed by #265
Open

cleanup aiopg.pool.Pool.cursor method #264

thehesiod opened this issue Jan 26, 2017 · 2 comments · May be fixed by #265

Comments

@thehesiod
Copy link
Contributor

thehesiod commented Jan 26, 2017

right now using this method is not async with nice, with the syntax:

        with (yield from pool.cursor()) as cur:
            yield from cur.execute("SELECT 1")

Based on the usage of context managers in aiopg, it should instead behavior like aiopg.create_pool, to yield the following usage:

        async with pool.cursor() as cur:
            yield from cur.execute("SELECT 1")

In order to accomplish this aiopg.pool.Pool.cursor should not be marked a coroutine, and the acquisition of the connection and cursor should not happen until __aenter__ of _PoolCursorContextManager. With the current design probably the easiest way would be to pass a coroutine closure to _PoolCursorContextManager to return the conn and cur during __aenter__

@thehesiod thehesiod linked a pull request Jan 26, 2017 that will close this issue
@thehesiod
Copy link
Contributor Author

thehesiod commented Jan 26, 2017

I've added a sample impl here: #265

@dave-shawley
Copy link

dave-shawley commented Sep 30, 2020

I just ran into this. The documented usage is:

Core API Reference — Welcome to AIOPG 2020-09-30 07-10-25

https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Pool.cursor

When I try this in Python 3.8.4, it does fail since cursor() is a co-routine instead of a async context manager:

zsh% python -m asyncio
asyncio REPL 3.8.4 (tags/v3.8.4:dfa645a65e, Jul 16 2020, 06:56:07)
[Clang 11.0.0 (clang-1100.0.33.16)] on darwin
Use "await" directly instead of "asyncio.run()".
Type "help", "copyright", "credits" or "license" for more information.
>>> import asyncio
>>> import aiopg
>>> pool = aiopg.Pool('postgresql://postgres:[email protected]:32778',
...                   minsize=1, maxsize=5, timeout=5.0, enable_json=True,
...                   enable_hstore=False, enable_uuid=True, echo=False,
...                   on_connect=None, pool_recycle=-1)
>>> async with pool.cursor() as c:
...     await c.execute('SELECT 1')
...
<console>:1: RuntimeWarning: coroutine 'Pool.cursor' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
  File "/Users/daveshawley/opt/lib/python3.8/concurrent/futures/_base.py", line 439, in result
    return self.__get_result()
  File "/Users/daveshawley/opt/lib/python3.8/concurrent/futures/_base.py", line 388, in __get_result
    raise self._exception
  File "<console>", line 1, in <module>
AttributeError: __aexit__
>>>

The cleanest spelling seems to be:

>>> with await pool.cursor() as c:
...    await c.execute('SELECT 1')
...    row = await c.fetchone()
...

At the very least, we should update the documentation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants