3

In PostgreSQL, I created a new table and assigned a new sequence to the id column. If I insert a record from the PostgreSQL console it works but when I try to import a record from from Rails, it raises an exception that it is unable to find the associated sequence.

Here is the table:

\d+ user_messages;
                                                  Table "public.user_messages"
   Column    |            Type             |                         Modifiers                          | Storage  | Description 
-------------+-----------------------------+------------------------------------------------------------+----------+-------------
 id          | integer                     | not null default nextval('new_user_messages_id'::regclass) | plain    | 

But when I try to get the sequence with the SQL query which Rails uses, it returns NULL:

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

(1 row)

The error being raised by Rails is:

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'

This problem only occurs when I use the ActiveRecord extension for importing bulk records, single records get saved through ActiveRecord.

How do I fix it?

4

1 回答 1

6

我认为您的问题是您手动设置了所有这些,而不是使用serial列。当您使用serial列时,PostgreSQL 将创建序列,设置适当的默认值,并确保序列由相关的表和列拥有。来自精美手册

pg_get_serial_sequence(table_name, column_name)
获取序列或大序列列使用的序列的名称

但是您没有使用serialbigserial因此pg_get_serial_sequence无济于事。

您可以通过以下方式解决此问题:

alter sequence new_user_messages_id owned by user_messages.id

我不确定这是否是一个完整的解决方案,并且有人(嗨 Erwin)可能会填补缺失的部分。

serial通过使用作为列的数据类型,您可以在此处省去一些麻烦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)
于 2012-05-11T07:33:59.570 回答