3

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を介して保存されます。

どうすれば修正できますか?

4

1 に答える 1

6

あなたの問題は、これらすべてをserialカラムを使用するのではなく、手作業で設定することだと思います。列を使用するserialと、PostgreSQLはシーケンスを作成し、適切なデフォルト値を設定し、シーケンスが問題のテーブルと列によって所有されていることを確認します。細かいマニュアルから:

pg_get_serial_sequence(table_name, column_name)
シリアルまたはbigserial列が使用するシーケンスの名前を取得します

しかし、あなたは使っていない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 に答える