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 | 

但是,當我試圖讓與SQL查詢其Rails使用序列,則返回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列使用

序列的名字,但你不使用serialbigserial所以pg_get_serial_sequence也無濟於事。

您可以通過執行解決這個問題:

alter sequence new_user_messages_id owned by user_messages.id 

我不知道這是否是一個完整的解決方案和某人(喜歐文)可能會在失位填寫。

通過使用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) 
+0

感謝這個解釋。我看到了這個確切的問題,'pg_get_serial_sequence'返回'NULL'。奇怪的是,在我的開發機器上,它可以正常工作,但是在構建服務器上,我得到了異常。有任何想法嗎? –

+0

@JimStewart:你在使用'serial'列還是試圖用手來連接序列? –

+0

我發現問題的根源在於序列是獨立創建的,然後我們的表格被創建爲使用它們的'id integer',而不是'id sequence'(長篇故事)。在Rails 3.1中出現的原因是舊版本的ActiveRecord會試圖查詢數據庫,如果失敗了,會假定默認的'tablename_columname_seq'會起作用。現在ActiveRecord不再落後於任何東西,所以映射必須在那裏。感謝您的詳細解決方案!我們正在使用你的'alter sequence'來修復我們的數據庫。 –