获得"价值" 3000002000"超出整数范围"

时间:2016-05-29 21:25:55

标签: ruby-on-rails postgresql ruby-on-rails-4 milliseconds bigint

我正在使用带有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
);

4 个答案:

答案 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失败。