2014-01-15 122 views
1

我有一個模型,用pg gem將數據直接加載到數據庫。在to_csv實例方法序列「setval」操作與Postgres在Rails中的「nextval」不一樣3.2.16

self.class.select("nextval('apps_id_seq'::regclass)").first['nextval'] 

:這是通過動態創建一個CSV文件,並指派值到id場致電。

這在生產中很有效。但是,我正在填寫一些測試,如果這個測試是首先運行的,或者它本身運行,那麼它會失敗,因爲DB剛剛被gem重置並且序列被重置。但他們沒有獲得初始價值。

Postgres文檔說你可以在有問題的序列上調用setval來設置它。因此,讓我們說,我想將它設置爲1開始,所以下一次nextval被調用時,它會返回一個1:

select setval('apps_id_seq'::regclass, 1, false); 

但正如我所說nextval我不能把這種以同樣的方式上面,因爲它只是簡單的不起作用。它返回nil,並且不設置序列。

的東西不重複我嘗試:

self.class.select("setval('apps_id_seq'::regclass)").first 
App.connection.execute("select setval('apps_id_seq'::regclass,1,false)") 
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1)") 
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)") 
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)") 

也不及其作品的任意組合,它只是refuses工作。我不知道這是不是一個pg寶石問題。

UPDATE

這些陳述中development模式下工作:

App.select("setval('apps_id_seq'::regclass,1)").first 

和:

App.select("nextval('apps_id_seq'::regclass)").first 

然而,在test都沒有工作。

,但這些言論並在test模式下工作:

ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)").first 

和:

ActiveRecord::Base.connection.execute("select nextval('apps_id_seq'::regclass)").first 

在兩種環境中,唯一的區別,就我所看到的,是一個具有數據,而另一個則沒有。我的測試數據庫是使用從structure.sql文件創建的。

回答

1

setvalnextval將工作,無論表中是否有序列連接到的數據。一個序列可以創建並遞增,甚至不需要關聯到現有表的列。當您使用Model.select執行原始SQL,ActiveRecord的生成from子句中使用的SQL爲您所使用的型號的表:

> App.select("setval('apps_id_seq'::regclass,1)").first 

    SELECT nextval('apps_id_seq'::regclass) 
    FROM "apps" ORDER BY "apps"."id" ASC LIMIT 1' 

=> nil 

因爲有在應用程序表中沒有記載,SETVAL功能是永遠執行。這就是爲什麼直接,因爲選擇沒有外來from子句同一選擇工程使用該連接時:

> ActiveRecord::Base.connection.execute("SELECT setval('apps_id_seq'::regclass, 1)").first 

    SELECT setval('apps_id_seq'::regclass, 1) 

=> {"setval"=>"1"} 

使用此表來執行SQL,這樣就可以保證setval功能總是被判斷。

+0

在更新您的問題時,您會說'這些陳述可以在測試模式下工作'。我不清楚究竟是什麼不工作使用'''ActiveRecord :: Base.connection.execute()''' –

+0

我昨天必須轉過身來。您的回答是正確的,感謝您的幫助。正在運行: ActiveRecord :: Base.connection.execute運行''''setval'''如果App.count == 0 修復了這個問題。 – AKWF