连接到PostgreSQL数据库时,Python打印加载“动画”

问题描述

(欢迎提供有关如何重新命名标题提示。)

我正在使用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),但是没有达到我想要的效果。我确实得到了点,但是由于返回了连接对象,即使无法建立任何连接,我的其余代码也无法按预期工作。我尝试更多地研究异步psycopg2。但是这种方法似乎带来了很多额外的工作。我只希望它异步连接,但是一旦存在连接,我的execute()绝对不应该异步工作。

解决方法

按照dirn的建议,我使用asyncpg重写了代码:

import asyncpg
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 = await asyncpg.connect(**conn_params)

        except TimeoutError:
            print("Could not connect to the database. Retrying...")

        finally:
            if conn:
                print("Successfully connected to database. "
                      "Now closing connection...")
                await conn.close()


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()

在此特定示例中,这产生了所需的结果。现在来看一下它如何与我程序的其余部分一起工作...