Ruby on rails 新分配的序列不工作

Ruby on rails 新分配的序列不工作,ruby-on-rails,ruby-on-rails-3,postgresql,activerecord,rails-postgresql,Ruby On Rails,Ruby On Rails 3,Postgresql,Activerecord,Rails Postgresql,在PostgreSQL中,我创建了一个新表,并为id列分配了一个新序列。如果我从PostgreSQL控制台插入一条记录,它可以工作,但是当我尝试从Rails导入一条记录时,它会引发一个异常,即它无法找到关联的序列 这是表格: \d+ user_messages; Table "public.user_messages" Column | Type

在PostgreSQL中,我创建了一个新表,并为
id
列分配了一个新序列。如果我从PostgreSQL控制台插入一条记录,它可以工作,但是当我尝试从Rails导入一条记录时,它会引发一个异常,即它无法找到关联的序列

这是表格:

\d+ user_messages;
                                                  Table "public.user_messages"
   Column    |            Type             |                         Modifiers                          | Storage  | Description 
-------------+-----------------------------+------------------------------------------------------------+----------+-------------
 id          | integer                     | not null default nextval('new_user_messages_id'::regclass) | plain    | 
但是,当我尝试使用Rails使用的SQL查询获取序列时,它返回NULL:

select pg_catalog.pg_get_serial_sequence('user_messages', 'id');
 pg_get_serial_sequence 
------------------------

(1 row)
Rails引发的错误是:

UserMessage.import [UserMessage.new]
NoMethodError: undefined method `split' for nil:NilClass
    from /app/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:910:in `default_sequence_name'
只有当我使用ActiveRecord扩展来导入批量记录时,这个问题才会发生,单个记录通过ActiveRecord保存


如何修复它?

我认为您的问题在于,所有这些都是手动设置的,而不是使用
串行
列。当您使用
serial
列时,PostgreSQL将创建序列,设置适当的默认值,并确保序列为相关表和列所拥有。从:

pg\u get\u serial\u序列(表名、列名)

获取序列或bigserial列使用的序列的名称

但是您没有使用
serial
bigserial
,因此
pg\u get\u serial\u sequence
不会有帮助

您可以通过执行以下操作来解决此问题:

alter sequence new_user_messages_id owned by user_messages.id
我不确定这是否是一个完整的解决方案,可能会有人(hi Erwin)来填补缺失的部分

通过使用作为
id
列的数据类型,您可以在这里省去一些麻烦。这将为您创建并连接序列

例如:

=> create sequence seq_test_id;
=> create table seq_test (id integer not null default nextval('seq_test_id'::regclass));
=> select pg_catalog.pg_get_serial_sequence('seq_test','id');
 pg_get_serial_sequence 
------------------------

(1 row)
=> alter sequence seq_test_id owned by seq_test.id;
=> select pg_catalog.pg_get_serial_sequence('seq_test','id');
 pg_get_serial_sequence 
------------------------
 public.seq_test_id
(1 row)

谢谢你的解释。我看到了这个确切的问题,
pg\u get\u serial\u sequence
正在返回
NULL
。奇怪的是,在我的开发机器上,它可以像这样工作,但是在构建服务器上,我得到了异常。有什么想法吗?@JimStewart:你是在使用
serial
列还是试图手动连接序列?我发现问题的根源是序列是单独创建的,然后我们的表是使用它们创建的
id integer
,而不是
id sequence
(说来话长)。Rails 3.1中出现这种情况的原因是,较旧版本的ActiveRecord会尝试查询数据库,如果查询失败,则会基于默认的
tablename\u columname\u seq
可以工作的假设。现在ActiveRecord不再依赖于任何东西,因此映射必须存在。感谢您的详细解决方案!我们正在使用您的
alter sequence
来修复我们的数据库。关于上面示例代码的另一个简要说明:默认Postgres序列名称是
table\u column\u seq
,而不是
seq\u table\u column
,因此,如果有人需要执行此手册
alter sequence
修复,请记住这一点。