我正在使用带有PostGre数据库的Rails 4.2.3。我希望我的数据库中的列存储数毫秒 - 注意,不是时间戳,而是持续时间(以毫秒为单位)。所以我创建了我的专栏
time_in_ms | bigint
但是,当我在Rails中存储一个值时,我得到以下错误
ActiveRecord::StatementInvalid (PG::NumericValueOutOfRange: ERROR: value "3000002000" is out of range for type integer
: INSERT INTO "my_object_times" ("time_in_ms", "my_object_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"):
app/controllers/my_objects_controller.rb:31:in `update'
似乎数字“3000002000”小于列的最大值(我正在阅读的是“9223372036854775807”),所以我想知道还有什么问题以及如何解决它。
编辑:要提供更多信息,请在我的db / schema.rb文件中描述相关列...
create_table "my_object_times", force: :cascade do |t|
...
t.integer "time_in_ms", limit: 8
编辑2:以下是PSQL
中create table的输出CREATE TABLE my_object_times (
id integer NOT NULL,
first_name character varying,
last_name character varying,
time_in_ms bigint,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
name character varying,
age integer,
city character varying,
state_id integer,
country_id integer,
overall_rank integer,
age_group_rank integer,
gender_rank integer
);
答案 0 :(得分:5)
在我最初尝试在db中创建bigint字段之前,我曾经遇到过这种情况,由于某种原因,模型认为它是一个整数,即使模式和迁移文件将其指定为bigint。
例如:我有此迁移文件
class CreateSecureUserTokens < ActiveRecord::Migration
def change
create_table :secure_user_tokens do |t|
t.integer :sso_id, null: false, length: 8
t.string :token, null: false
t.timestamps null: false
end
end
end
注意,它具有包含的长度:8要求使整数变为bigint。但是,在我运行迁移后,我遇到了与您相同的问题。最后,我刚刚创建了另一个迁移来尝试解决问题,并且它有效。这是我用来解决问题的迁移:
class ModifySecureTokensForLargerSsoIdSizes < ActiveRecord::Migration
def change
change_column :secure_user_tokens, :sso_id, :integer, limit: 8
end
end
因此,如果我们改变它以满足您的需求,那就是:
class ObjectTimesBigInt < ActiveRecord::Migration
def change
change_column :my_object_times, :time_in_ms, :integer, limit: 8
end
end
希望有所帮助! -Charlie
答案 1 :(得分:1)
编辑: 我刚刚重新阅读此内容,我的原始答案在您的情况下实际上没有意义。我相信您需要在该列之外寻找答案,并且手动确认您认为您对其状态的所有了解。任何细节的添加都有助于我们找到正确的答案。
设置断点以逐步执行请求,看看您是否可以发现integer
create_table&#34; my_object_times&#34;,force :: cascade do | t | ... t.integer&#34; time_in_ms&#34;,限制:8
<强> t.integer
- 这对我来说就像是罪魁祸首。
...
好吧,我试过,我最后的想法是它必须与某种Rails请求中间件有关,但我不知道具体可能是什么。请求路径中的某些内容认为该列是整数。到目前为止,我还没有理解Rails迁移数据类型是如何工作的,所以我学到了一些东西。 (而且我整天都在钓鱼,所以我今天算上一场胜利。祝你好运!
答案 2 :(得分:1)
我想,可能无法从my_object_times
文件创建表schema.rb
,或者可能会在其他迁移文件中覆盖表bigint
。因为在迁移文件中,具有限制8的整数列本身就是class ChangeTimeInMsToBigint < ActiveRecord::Migration
def change
execute <<-SQL
ALTER TABLE my_object_times
ALTER COLUMN time_in_ms TYPE bigint USING time_in_ms::bigint
SQL
end
end
。所以你应该从PG-admin交叉检查表定义。如果列不是bigInt,则运行以下迁移
Root Cause
答案 3 :(得分:-4)
bigint
是64位,而Rails是32位。
3000002000
大于2^32
。这就是为什么将它转换为32位整数会导致NumericValueOutOfRange
失败。