4

我有一個通過遷移創建的MATERIALIZED VIEW未填充Postgres實例化視圖的ActiveRecord遷移

class MyView < ActiveRecord::Migration 
    def up 
    ActiveRecord::Base.connection.execute <<-SQL 
    CREATE MATERIALIZED VIEW my_view AS (
     SELECT DISTINCT something, something_else, other.thing as real_thing, thing.some_id 
      FROM some_table 
      JOIN another_table on another_table.id = something 
      JOIN one_more_table on some_table.id = other_id 
      ORDER BY order_column) 
     WITH DATA; 
    SQL 

    add_index :table, [:key_part_one, :key_part_two] 
    end 

    ... 
end 

注意:我已經混淆了SELECT語句,只是相信我,它的工作原理。

這裏需要注意的重要部分是我已經明確地調用了WITH DATA,因此視圖應該立即填充並可掃描。

這沒有發生。遷移運行,下面

== MyView: migrating ======================== 
== MyView: migrated (0.0763s) =============== 

後來在我們看到db:refresh顯示以下

Reindexing Something... 
Reindex queued 
Reindexing Another... 
Reindex queued 
Reindexing SomeOtherThing... 
Reindex queued 
Reindexing One::OtherThing... 
Reindex queued 
Reindexing MyViewModel... 
rake aborted! 
ActiveRecord::StatementInvalid: PG::ObjectNotInPrerequisiteState: ERROR: materialized view "my_view" has not been populated 
HINT: Use the REFRESH MATERIALIZED VIEW command. 

嗯,什麼?我宣稱WITH DATA。我還有另一個連續遷移,在視圖上明確調用REFRESH MATERIALIZED VIEW命令。

無濟於事,爲了使rake db:refresh任務完成,我必須進入並手動刷新視圖。

有趣的注意,在structure.sql文件,其顯示爲無數據

CREATE MATERIALIZED VIEW my_view AS (
    SELECT DISTINCT something, something_else, other.thing as real_thing, thing.some_id 
     FROM some_table 
     JOIN another_table on another_table.id = something 
     JOIN one_more_table on some_table.id = other_id 
     ORDER BY order_column) 
    WITH NO DATA; 

創建我認爲這纔是真正的問題,但我不知道修復/解決辦法的。它也令人困惑,因爲即使它是用無數據創建的,隨後的REFRESH MATERIALIZED VIEW應該填充它並將其標記爲可掃描。

有沒有Postgres或AR的問題,我不知道是阻止我填充這個物化視圖?

+0

你有沒有嘗試過創建和使用你的視圖沒有ActiveRecord和Rails的方式? –

回答

1

我知道這個問題在2年前被問過了,但也許我的回答對其他人有用。

嘗試使用scenic gem。我最近寫了關於它的a blog post