时间戳无法保存 – postgresql
我有以下代码片段:
class Foo include DataMapper::Resource property :id, Serial property :timestamp, DateTime end
我只想将当前时间转换为ms:
class Time def to_ms (self.to_f * 1000.0).to_i end end def current_time time = Time.now return time.to_ms end time = current_time # => 1352633569151
但是当我要用上面的时间戳保存Foo时,它就无法保存到数据库中而且我没有收到任何错误消息。
foo = Foo.new foo.timestamp = time foo.save
任何的想法?
你是否使用正确的格式:datetime
属性?
应该是这样的:
DateTime.now.to_s => "2012-11-11T14:04:02+02:00"
或“本机”DateTime对象,没有任何转换。
DataMapper将根据使用的适配器将其转换为相应的值。
另外,保存项目时会引发exception:
DataMapper::Model.raise_on_save_failure = true
这是一个全球性的设置,即所有模型都会引发exception。
只使某些模型表现得像这样:
YourModel.raise_on_save_failure = true
http://datamapper.org/docs/create_and_destroy.html
请参见“保存失败时引发exception”一章
顺便说一下,在保存项目之前看看你的项目有什么问题,使用和item.valid?
和item.errors
foo = Foo.new foo.timestamp = time if foo.valid? foo.save else p foo.errors end
我复制了你的代码并得到了以下错误:
@errors={:timestamp=>["Timestamp must be of type DateTime"]}
在这里查看现场演示
PostgreSQL数据类型将是timestamp with time zone
timestamp
或timestamp with time zone
。 但这与你正在做的事情相矛盾。 您获取纪元值并乘以1000.您必须将其保存为integer
或某种数字类型 。
有关在Postgres中处理时间戳的更多信息,请参阅此相关答案。
我会将值保存timestamp with time zone
(不是乘法)。 如果需要,你总是可以从中提取ms。
如果需要将Unix纪元值转换回时间戳,请使用:
SELECT to_timestamp(1352633569.151); --> timestamptz 2012-11-11 12:32:49.151+01
只需保存“现在”
如果你真的想保存“现在”,即当前的时间点,那么让Postgres为你做。 只需确保数据库服务器具有可靠的本地时间 – 安装ntp 。 这通常更可靠,准确和简单。
将timestamp列的DEFAULT
设置为now()
或CURRENT_TIMESTAMP
。
如果您想要timestamp
而不是timestamptz
您仍然可以使用now()
,根据服务器时区设置将其转换为“本地”时间。 或者,为了获得给定时区的时间:
now() AT ZIME ZONE 'Europe/Vienna' -- your time zone here
或者,在您的特定情况下,因为您似乎只需要三个小数位: now()::timestamp(3)
或CURRENT_TIMESTAMP(3)
或CURRENT_TIMESTAMP(3) AT ZIME ZONE 'Europe/Vienna'
。
或者,如果将列的类型定义为timestamp(3)
,则会将所有时间戳值强制转换为该类型,并自动舍入为3个小数位数。
所以这就是你所需要的:
CREATE TABLE tbl ( -- other columns ,ts_column timestamp(3) DEFAULT now() );
该值在INSERT
自动设置,您甚至不必提及该列。
如果你想更新它ON UPDATE
,添加一个如下所示的TRIGGER :
触发function:
CREATE OR REPLACE FUNCTION trg_up_ts() RETURNS trigger AS $BODY$ BEGIN NEW.ts_column := now(); RETURN NEW; END $BODY$ LANGUAGE plpgsql VOLATILE
触发:
CREATE TRIGGER log_up_ts BEFORE UPDATE ON tbl FOR EACH ROW EXECUTE PROCEDURE trg_up_ts();
现在, 一切都自动运作。
如果那不是你想要的, @ slivu的回答似乎很好地涵盖了Ruby方面。
我不熟悉PostgreSQL,但为什么要为timestamp
(这是一个DateTime)分配一个Fixnum( time
)? 在生成SQL之前,您的模型必须无法将time
转换为正确的DateTime值。
试试foo.save!
。 我很确定你会看到一个错误,或者从PostgreSQL报告,说1352633569151
不是表列的有效值,或者你的模型会说它无法将1352633569151
解析为有效的DateTime。
foo.timestamp = Time.now
或foo.timestamp = '2012-11-11 00:00:00'
是可行的。