aio-libs / aiomysql

aiomysql is a library for accessing a MySQL database from the asyncio
https://aiomysql.rtfd.io
MIT License
1.76k stars 256 forks source link

Support Python 3.7's asyncio.run() syntax~ #407

Open leafonsword opened 5 years ago

leafonsword commented 5 years ago

As of Python 3.7, asyncio has many new easy-to use feature, aiomysql's usage syntax is long and difficult to use;

Hope asyncio could support Python 3.7's new feature such as asyncio.run(), asyncio.create_task(), asyncio.gather()

asvetlov commented 5 years ago

Please elaborate your proposal

leafonsword commented 5 years ago

@Askaholic with Python 3.7's new feature--asyncio.run(), asyncio.create_task(), asyncio.gather(), async syntax is simple and elegant, for example:

import pendulum 
import asyncio

async def test(name):
    print(f'Begin:{name} {pendulum.now()}')
    await asyncio.sleep(2)
    print(f'End:{name} {pendulum.now()}')

async def main():
    task1 = asyncio.create_task(test('A'))
    task2 = asyncio.create_task(test('B'))

    await task1
    await task2

asyncio.run(main())
import pendulum 
import asyncio

async def test(name):
    print(f'Begin:{name} {pendulum.now()}')
    await asyncio.sleep(2)
    print(f'End:{name} {pendulum.now()}')

async def main():
   await asyncio.gather(
        test('Bob'),
        test('Amy'),
        test('Mike'),
    )

asyncio.run(main())
asvetlov commented 5 years ago

What prevents you to use this elegant syntax with aiomysql right now?

leafonsword commented 5 years ago

@leafonsword aiomysql's document doesn't have asyncio.run(), asyncio.create_task(), asyncio.gather() syntax example, just this:

import asyncio
import aiomysql

loop = asyncio.get_event_loop()

@asyncio.coroutine
def test_example():
    conn = yield from aiomysql.connect(host='127.0.0.1', port=3306,
                                       user='root', password='', db='mysql',
                                       loop=loop)

    cur = yield from conn.cursor()
    yield from cur.execute("SELECT Host,User FROM user")
    print(cur.description)
    r = yield from cur.fetchall()
    print(r)
    yield from cur.close()
    conn.close()

loop.run_until_complete(test_example())
asvetlov commented 5 years ago

But all these things just work :) Would you communicate with @terrycain and propose pull request for docs improvement. run_until_complete should stay for a while making python 3.7 the minimal supported version. Otherwise, it confuses people who use Python 3.6 for example. yield from can be replaced with await right now.

leafonsword commented 5 years ago

@asvetlov I'm still learning asyncio, after I dive into async syntax, I will try to using asyncio.run(), asyncio.create_task(), asyncio.gather() with aiomysql, and push a pr

huwcbjones commented 4 years ago

Be warned that if you use asyncio.gather() then you need a new connection per coroutine, otherwise you'll end up with invalid packet orders. Othewise you end up with all the running coroutines sharing the same connection which means when a different coroutine is scheduled to run, the connection could be in the middle of a different query and therefore you'll get packet out of order errors.