我的代码每小时运行一次,并正确地记录时间,但由于某种原因,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.
1条答案
按热度按时间xqk2d5yq1#
解决了问题的答案在评论和以下结果:
1.使用psycopg2连接池并编写一个类来创建一个上下文,其中的连接将在一个或一组事务或select语句之后自动关闭
1.使用CURRENT_TIMESTAMP函数