将表列的数据类型从timestamp更改为bigint

时间:2014-04-16 03:38:22

标签: sql postgresql types ddl

我正在使用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

2 个答案:

答案 0 :(得分:8)

ALTER TABLE tablename ALTER COLUMN updated
TYPE bigint USING EXTRACT(EPOCH FROM updated);

Per documentation:

  

表示datetimestamp值,即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,) )