时间戳无法保存 – 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 timestamptimestamp 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.nowfoo.timestamp = '2012-11-11 00:00:00'是可行的。