1

我有一个遗留数据库,我需要它来为 Rails 应用程序提取数据。

每个表被拆分为多个带有数字后缀的表。每个表都保存一天中四个小时的数据。

我们有“widget_status”表。该表实际上并不保存数据。

现有的表是:

  1. 小部件_状态_0
  2. 小部件_状态_1
  3. 小部件_状态_2
  4. 小部件_状态_3
  5. 小部件_状态_4
  6. 小部件_状态_53

每个表包含四个小时的数据。

此查询有效:

( SELECT timestamp, some_field FROM widget_status_0  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_1  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_2  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_3  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_4  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod )  
 UNION 
( SELECT timestamp, some_field FROM widget_status_5  
 WHERE widget_sn = \@widgetsn and timestamp > $timePeriod ) LIMIT 200 

我正在尝试创建一个 Rails 模型“小部件”,它将使用 aunion或类似的东西查询六个基础表,因此其余代码将忽略尝试处理六个表。

我有多个遵循这种模式的表,并且希望能够抽象出 6 个表的处理,因此在其余代码中,我可以正常使用 find 等。谁能建议如何使用 AREL 来做到这一点?或者任何一种既好又简单的方法?

4

1 回答 1

0

不完全是一个答案:不幸的是,我不确定你如何使用 AR 来做这种事情,除非你有能力创建一个数据库视图(正如你在评论中提到的那样)。

如果没有 DB 视图,您将失去很多 AR 的魔力,包括查询方法和对象的自动实例化。

但是,arel 可以帮助您构建查询(注意:以下内容未经测试,您可能需要对其进行调整,但您会得到精神)。

class WidgetStatus    

  # when given a block, this method will apply the same arel chain 
  # to all tables and union them.
  def self.build_query 
    (0..5).map do |i| 
      arel_chain = Arel::Table.new("widget_status_#{i}") 
      arel_chain = yield arel_chain if block_given?
      arel_chain
    end.inject(){|chain, next| chain.union next }
  end

end

现在你可以做类似的事情:

query = WidgetStatus.build_query do |table| 
  table
    .project( :timestamp, :some_field )
    .where( 
      table[:widget_sn].eq( @sn )
      .and( table[:timestamp].get( @t ) 
     )
end

并用于ActiveRecord::Base.connection.select_all query获取有用的数据。

于 2013-02-12T12:00:49.190 回答