1

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) 

レールによって提起されたエラーがあります:

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

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

pg_get_serial_sequence(table_name, column_name)
は、シリアルまたはBIGSERIAL列が

を使用しています。しかし、あなたがpg_get_serial_sequenceが助けにはなりませんのでserialまたはbigserialを使用していないことをシーケンスの名前を取得します。

あなたが行うことによってこの問題を解決することができます:私は、これは完全なソリューションと誰か(HIアーウィン)であるかどうかわからないんだけど

alter sequence new_user_messages_id owned by user_messages.id 

はおそらく不足しているビットに記入します。

id列のデータ型としてserialを使用すると、ここで何らかのトラブルを回避できます。それはあなたのためにシーケンスを作成し、接続します。例えば

:この説明のために

=> 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) 
+0

感謝。私はこの正確な問題を見ており、 'pg_get_serial_sequence'は' NULL'を返しています。奇妙なことは、私の開発マシンでは、このようにうまく動作しますが、ビルドサーバーでは例外が発生します。何か案は? –

+0

@JimStewart: 'serial'カラムを使用しているのですか、手でシーケンスを接続しようとしていますか? –

+0

問題の根本は、シーケンスが孤立して作成されていて、テーブルが 'id sequence'(long story)ではなく' id integer'として作成されていることです。これがRails 3.1で切り詰めたのは、古いバージョンのActiveRecordがDBにクエリを実行しようとするため、失敗した場合、デフォルトの 'tablename_columname_seq'が動作するという仮定に戻ります。これで、ActiveRecordは何にも転用されなくなり、マッピングがそこになければなりません。詳細なソリューションをありがとう!私たちはあなたの 'alter sequence'を使ってDBを修正しています。 –

関連する問題