【发布时间】:2020-12-14 10:43:24
【问题描述】:
(欢迎提供有关如何改写标题的提示。)
我正在使用 psycopg2 和 asyncio。我想要发生的是用户有一些迹象表明程序正在做某事。我有一个花哨的“\ | / -”动画,但为了简单起见,我希望它每秒打印一个点。
到目前为止我所拥有的:
import psycopg2
import asyncio
async def heartbeat(seconds):
for sec in range(seconds):
print(".")
await asyncio.sleep(1)
async def conn_test():
conn_params = {"database": "testdb", "user": "postgres",
"password": "my_pw"}
conn = None
print("Attempting to connect to database...")
while not conn:
try:
conn = psycopg2.connect(**conn_params)
except (Exception, psycopg2.Error) as error:
print(error)
finally:
if conn:
conn.close()
print("Successfully connected to database. Now closing connection...")
else:
print("Could not connect to the database. Retrying...")
async def main():
t1 = loop.create_task(heartbeat(10))
t2 = conn_test()
await asyncio.wait([t1, t2])
if __name__ == "__main__":
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
except Exception as e:
print(e)
finally:
loop.close()
我得到什么(如果我故意阻止它连接)
.
Attempting to connect to database...
(直到 psycopg2 超时。)
我想要什么:
.
Attempting to connect to database...
.
.
.
.
.
(等等)
我试过psycopg2.connect(**conn_params, async_=True),但没有达到我想要的效果。我确实得到了点,但是由于返回了连接对象,即使无法建立连接,我的其余代码也无法按预期工作。我尝试进一步研究 async psycopg2。但这种方法似乎带来了很多额外的工作。我只是希望它异步连接,但是一旦连接存在,我的execute()s 肯定不能异步工作。
【问题讨论】:
-
conn_test不会等待任何东西,因此在完成之前不会给其他任何东西运行的机会。您应该考虑使用异步感知驱动程序。不过,这仍然可能不会让您获得想要的结果。您最好使用单独的线程或进程来更新 UI。 -
我尝试了
conn = await psycopg2.connect(**conn_params),但后来我得到了object psycopg2.extensions.connection can't be used in 'await' expression。 -
对。 psycopg2 不是异步感知库。您需要使用不同的库,例如 asyncpg。
-
但是一旦连接存在,我的
execute()s 肯定不能异步工作 - 如果你在这里写的是真的,你不会对asyncpg满意.异步不是您可以在程序的一小部分(如辅助线程)中使用的东西,它是一个影响一切的架构决策。 -
你需要把
await放在每个前面。
标签: python python-3.x asynchronous python-asyncio psycopg2