postgresql psycopg2的输出与命令行不同

6pp0gazn  于 2022-12-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(171)

当我直接在数据库上运行select now() - pg_last_xact_replay_timestamp() AS replication_delay时,输出为

replication_delay
-------------------
 -00:00:00.55072
(1 row)

当我把同样的查询放到python脚本中时

import psycopg2

 try:
    connection = psycopg2.connect(user="postgres",
                              host="x.x.x.x",
                              port="5432",
                              database="postgres")

    cursor = connection.cursor()
    postgreSQL_select_Query = "select now() - pg_last_xact_replay_timestamp() AS 
    replication_delay;"

    cursor.execute(postgreSQL_select_Query)
    records = cursor.fetchall()
    print (records)

    except (Exception, psycopg2.Error) as error:
    print("Error while fetching data from PostgreSQL", error)

    finally:
    # closing database connection.
        if connection:
           cursor.close()
           connection.close()
           print("PostgreSQL connection is closed")

输出为

[(datetime.timedelta(days=-1, seconds=86399, microseconds=521719),)]

我怎样才能让脚本的输出像命令行输出一样显示呢?

00:00:00.55072
f2uvfpb9

f2uvfpb91#

因为使用fetchall获取所有行,所以会得到一个元组数组,因为只获取一行,所以使用fetchone只获取一个元组。
然后获取元组中的第一项。

cursor.execute(postgreSQL_select_Query)
records = cursor.fetchone()
delta = records[0]

现在你只剩下时间间隔了。
psycopg 2已经将Postgresql interval typeMap到一个datetime.timedelta对象。你需要格式化它。问题是,没有内置的方法来格式化timedelta。
更糟糕的是,datetime.timedelta(days=-1, seconds=86399, microseconds=521719是一种非常非常奇怪的表示-0.478281秒的方式,但这就是timedelta的工作原理,通常你只需要str(delta)就可以得到你想要的,但是当我们尝试上面的方法时,我们得到了-1 day, 23:59:59.521719,这是没有用的。
相反,如果它是负数,则取绝对值(这将把它变成datetime.timedelta(microseconds=478281)),把它变成字符串,然后加上负号。

from datetime import timedelta
from math import modf

def format_timedelta(delta):
  if delta < timedelta(0):
    return "-" + str(abs(delta))
  else:
    return str(delta)

相关问题