【发布时间】:2022-01-10 20:00:08
【问题描述】:
我正在尝试尽快从本地 Postgres 数据库加载数据,似乎性能最高的 python 包是asyncpg。我的代码是同步的,我反复需要加载数据块。我对将 async 关键字传播到我编写的每个函数不感兴趣,因此我试图将异步代码包装在同步函数中。
下面的代码可以工作,但是非常难看:
def connect_to_postgres(user, password, database, host):
async def wrapped():
return await asyncpg.connect(user=keys['user'], password=keys['password'],
database='markets', host='127.0.0.1')
loop = asyncio.get_event_loop()
db_connection = loop.run_until_complete(wrapped())
return db_connection
db_connection = connect_to_postgres(keys['user'], keys['password'],
'db', '127.0.0.1')
def fetch_from_postgres(query, db_connection):
async def wrapped():
return await db_connection.fetch(query)
loop = asyncio.get_event_loop()
values = loop.run_until_complete(wrapped())
return values
fetch_from_postgres("SELECT * from db LIMIT 5", db_connection)
在 Julia 我会做类似的事情
f() = @async 5
g() = fetch(f())
g()
但在 Python 中,我似乎不得不做相当笨重的事情,
async def f():
return 5
def g():
loop = asyncio.get_event_loop()
return loop.run_until_complete(f())
只是想知道是否有更好的方法?
编辑:后面的python示例当然可以使用
def fetch(x):
loop = asyncio.get_event_loop()
return loop.run_until_complete(x)
尽管如此,除非我遗漏了什么,否则仍然需要创建一个异步包装函数。
编辑 2:我确实关心性能,但希望使用同步编程方法。 asyncpg 比 psycopg2 快 3 倍,因为它的核心实现是在 Cython 而不是 Python 中,这在 https://magic.io/blog/asyncpg-1m-rows-from-postgres-to-python/ 中有更详细的解释。因此我希望包装这个异步代码。
编辑 3:提出这个问题的另一种方法是在 python 中避免"what color is your function" 的最佳方法是什么?
【问题讨论】:
-
您是如何得出
asyncpg性能最高的结论的?混合异步和同步代码会很麻烦,如果你想使用包或只使用同步包,为什么不让所有代码异步? -
@IainShelvington 根据github.com/MagicStack/asyncpg#performance,asyncpg 比(同步)psycopg2 快 3 倍。我确实更喜欢同步代码包
-
@Ajax1234 我相信这种方法会有更多的开销,因为它会创建一个新的事件循环并在每次调用时销毁它github.com/python/cpython/blob/…
标签: python asynchronous python-asyncio