我正在使用postgres,我有一个表格,其列数据类型为时区,没有时区。
我想将数据类型更改为bigint
。我试图在列中存储自1970年以来的秒数。像1397597908756
这样的大事。
我正在使用python,类似于:
d = dict() # create a dictionary, has key 'timestamp'
#get data from server and store in array
d.update(dict(timestamp=data[1]) #data[1] has the number of seconds
我多次触摸服务器所以存储在字典中是必不可少的。查询是:
cursor.execute("INSERT into tablename columname VALUES (%s)", (quote['timestamp'];
此时,抛出异常:
类型为timestamp的输入语法无效:1397597908756
所以我尝试将数据类型从timestamp without timezone
更改为bigint
。我做了:
ALTER TABLE tablename ALTER COLUMN columnname
SET DATA TYPE bigint USING updated::bigint;
我收到以下错误:
错误:无法将没有时区的类型时间戳转换为bigint
答案 0 :(得分:8)
ALTER TABLE tablename ALTER COLUMN updated
TYPE bigint USING EXTRACT(EPOCH FROM updated);
表示
date
和timestamp
值,即1970-01-01 00:00:00当地时间以来的秒数;
答案 1 :(得分:3)
欧文的回答是正确的,我只是想谈谈另一个方面。
我试图在列
中存储自1970年以来的秒数
请不要那样做。查询很烦人,并且与使用时间戳相比没有存储优势。
存储timestamp without time zone
。或者,最好使用timestamp with time zone
,以便根据客户端的TimeZone
设置进行适当调整。
如果客户端应用需要纪元秒数,则始终可以select extract(epoch from my_field), ...
。但实际上,您的应用应该能够正确使用日期。
目前尚不清楚您尝试通过切换到存储原始纪元秒来解决的问题;可能有必要的情况。但就个人而言,我不是做这样的事情,而是定义一个可更新的视图,返回epoch秒并将输入bigints转换为时间戳,以便存储在基础表中。所以应用程序会认为它有一个带有纪元秒的表,但它确实与时间戳一起工作。当然,我更愿意让我的应用程序首先正确地使用时间戳,如果某个客户端接口需要它,则在应用程序中转换为纪元秒。
在您的情况下,只需插入datetime.datetime
对象。
import datetime
# Convert epoch seconds into a Python datetime.datetime object that psycopg2 will
# understand as a date and insert as a PostgreSQL timestamp value.
ts = datetime.datetime.fromtimestamp(d['timestamp'])
cursor.execute("INSERT into tablename columname VALUES (%s)", (ts,) )