2010-05-31 88 views
3

您在Ruby中使用的数据库抽象/适配器是什么?我主要关注面向数据的功能,而不是那些使用对象映射的功能(如活动记录或数据映射器)。ruby​​的数据库抽象/适配器

我目前使用Sequel。还有其他选择吗?

我最感兴趣:

  • 简单,干净和非模糊API
  • 数据选择(明显),过滤和聚集
  • 原始值选择而不字段映射:SELECT COL1 ,col2,col3 => [val1,val2,val3]不是{:col1 => val1的散列...}
  • 能够传递要选择的列/值列表:select(array_of_columns)(not:dataset .select(:col1,:col2,:col3)需要列已知)
  • API以一致(和工作)的方式考虑表格模式'some_schema.some_table';也正因为这个反射(得到表模式)
  • 数据库反射:让表列,他们的数据库存储类型,也许适配器的抽象类型
  • 表创建的列表,删除
  • 能够与其他表的工作(插入,在一个循环中从另一个表中列举的选择,而不需要对取从表中所有记录更新)被枚举

目的是在编写代码的时间,这是相反的,以对象与未知结构来操作数据映射结构或大部分str通常是众所周知的。我不需要对象映射开销。

有什么选择,包括对象映射库的后端?

回答

5

我是Sequel的首席开发人员,所以这个回应显然是有偏见的,但我没有意识到任何你想做的任何Ruby数据库库。

看来某些你的欲望被认为在续集的限制,其中的一些可被寻址:

  • 原始值选择而不字段映射:SELECT COL1,COL2,COL3 => [VAL1,val2的, VAL3]不凑{:COL1 => VAL1 ...}

尝试:

DB[:table].filter([:col1, :col2, :col3].zip([1, 2, 3])) 
# SELECT * FROM table WHERE ((col1 = 1) AND (col2 = 2) AND (col3 = 3)) 

是微不足道的添加一个新的数据集的方法,提供一个更好的API˚F或以上:

DB[:table].bfilter([:col1, :col2, :col3], [1, 2, 3]) 
  • 能够通过列的列表/被选择的值:选择(array_of_columns)(未:数据集。在一致

    array_of_columns = [:col1, :col2, :col3] 
    DB[:table].select(*array_of_columns) 
    # SELECT col1, col2, col3 FROM table 
    
    • API考虑到表模式 'some_schema.some_table'(:选择(:COL1,:COL2,:COL3),这要求列已知)

    尝试和工作)的方式;也正因为这个反射(得到表模式)

续集涉及表模式:

DB[:schema__table] 
DB[:table.qualify(:schema)] 
# SELECT * FROM schema.table 

的任何地方,通常被认为是一个错误,这并不工作。我不确定你的意思是反思。同一个表名可以在多个模式中使用,因此表所在的模式通常是一个模棱两可的问题。

  • 数据库反射:让表列,他们的数据库存储类型,也许适配器的抽象类型

列作为符号的数组列表:

DB[:table].columns 
# => [:col1, :col2, :col3] 

架构信息:

DB.schema(:table) 
# [[:col1=>{:type=>:integer, :db_type=>'int(11)', :default=>nil, ...}], ...] 

:type是ruby类型的符号,:db_type是数据库类型字符串

  • 能够在一个循环从另一个表列举选择其他表(INSERT,UPDATE)的工作,而不需要来从表中的所有记录被枚举

我假设你所要求的东西,像这样的:

DB[:table].each do |row| 
    DB[:other_table].insert(:blah=>row[:blah]) 
end 

这并不正确地在续集一些适配器由于连接池使用在插入相同的数据库连接工作:other_table而仍在使用的是:选择上表。您可以解决此通过分片支持:

DB = Sequel.connect(..., :servers=>{:read_only=>{}}) 
DB[:table].each do |row| 
    DB[:other_table].insert(:blah=>row[:blah]) 
end 

在这种情况下,DB将使用:READ_ONLY碎片的选择上:表和:默认碎片上插入:other_table。您也可以明确指定碎片:

DB[:table].server(:read_only).each do |row| 
    DB[:other_table].server(:default).insert(:blah=>row[:blah]) 
end 

我并没有解决我想你知道,续集已经处理点。 Sequel并不能满足你的所有需求,但在这种情况下,我怀疑任何其他Ruby数据库库都会如此。