postgresql Postgres NOW()在asyncio任务中调用时返回不正确的时间

zvms9eto  于 2023-05-28  发布在  PostgreSQL
关注(0)|答案(1)|浏览(181)

我的代码每小时运行一次,并正确地记录时间,但由于某种原因,postgres HOW()返回错误的时间。
代码看起来像这样:

async def run():
    await before_startup()
    # ...

async def before_startup() -> None:
    loop = asyncio.get_event_loop()
    loop.create_task(interval_handler())

async def interval_handler():
    while True:
        logger.info("Handler:", datetime.datetime.now())
        for data in process_validity():
            pass

        # Wait to the next hour
        delta = datetime.timedelta(hours=1)
        now = datetime.datetime.now()
        next_hour = (now + delta).replace(microsecond=0, second=0, minute=0)
        wait_seconds = (next_hour - now).seconds
        await asyncio.sleep(1)  # Ensure unique per interval
        await asyncio.sleep(wait_seconds)

class Singleton(type):
    _instances = {}

    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(
                Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]

class Database(metaclass=Singleton):
    def __init__(self):
        self.connection = None

    def connect(self):
        self.connection = psycopg2.connect()

    def fetchmany(self, query: str, per: int, params: tuple | dict = None):
        cursor = self.connection.cursor(cursor_factory=RealDictCursor)
        cursor.execute(query, params)
        while True:
            result = cursor.fetchmany(per)
            yield result
            if not result:
                cursor.close()
                break

db = Database()
db.connect()

def process_validity() -> Generator[DataInterface, None, None]:
    db_now: datetime.datetime = db.fetchone("SELECT NOW()")['now'].replace(tzinfo=None)
    logger.info("NOW() is:", db_now)
    for users_set in db.fetchmany("SELECT ...", 100, ()):
        for user in users_set:
            yield user

if __name__ == "__main__":
    asyncio.run(run())

日志如下所示:

2023-05-20 15:00:00 +0000 INFO     Handler: 2023-05-20 15:00:00.775156
2023-05-20 15:00:00 +0000 INFO     NOW() is: 2023-05-20 13:49:35.873942

请注意,logger和datetime.datetime.now()得到的时间是正确的(15:00),而Postgres返回的时间是错误的(13:49)。会有什么问题呢?随着时间的推移,差距越来越大。
另外,我通过psql连接到容器并获得正确的时间;正确的时间也通过pycharm连接获得。此外,机器人启动后,任务会立即处理,此时一切都是正确的。然后,delta增加。
我的环境:Ubuntu 20.04.5 LTS(GNU/Linux 5.4.0-137-generic x86_64),Docker version 20.10.23,build 7155243,postgres:15.1-alpine,python 3.11.

xqk2d5yq

xqk2d5yq1#

解决了问题的答案在评论和以下结果:
1.使用psycopg2连接池并编写一个类来创建一个上下文,其中的连接将在一个或一组事务或select语句之后自动关闭
1.使用CURRENT_TIMESTAMP函数

相关问题