ruby的数据库抽象/适配器

Sti*_*ivi 3 ruby database-abstraction adapter sequel

您在Ruby中使用的数据库抽象/适配器是什么?我主要对数据导向的功能感兴趣,而不是那些具有对象映射的功能(如活动记录或数据映射器).

我目前正在使用续集.还有其他选择吗?

我最感兴趣的是:

  • 简单,干净,不含糊的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'; 也为此反思(从表中获取模式)
  • 数据库反射:获取表列的列表,它们的数据库存储类型以及可能的适配器抽象类型
  • 表创建,删除
  • 能够在循环中使用其他表(插入,更新)枚举来自另一个表的选择,而无需从枚举的表中获取所有记录

目的是在编写代码时操纵具有未知结构的数据,这与对象映射相反,其中结构或大多数结构通常是众所周知的.我不需要对象映射开销.

有哪些选项,包括对象映射库的后端?

Jer*_*ans 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))
Run Code Online (Sandbox Code Playgroud)

添加一个为上述提供更好API的新数据集方法是微不足道的:

DB[:table].bfilter([:col1, :col2, :col3], [1, 2, 3])
Run Code Online (Sandbox Code Playgroud)
  • 能够传递要选择的列/值列表:select(array_of_columns)(not:dataset.select(:col1,:col2,:col3),它要求列已知)

尝试:

array_of_columns = [:col1, :col2, :col3]
DB[:table].select(*array_of_columns)
# SELECT col1, col2, col3 FROM table
Run Code Online (Sandbox Code Playgroud)
  • API以一致(和工作)的方式考虑表模式'some_schema.some_table'; 也为此反思(从表中获取模式)

续集处理表模式:

DB[:schema__table]
DB[:table.qualify(:schema)]
# SELECT * FROM schema.table
Run Code Online (Sandbox Code Playgroud)

任何不起作用的地方通常被认为是一个错误.我不确定你的意思是什么.可以在多个模式中使用相同的表名,因此表所在的模式通常是一个模糊的问题.

  • 数据库反射:获取表列的列表,它们的数据库存储类型以及可能的适配器抽象类型

列为符号数组:

DB[:table].columns
# => [:col1, :col2, :col3]
Run Code Online (Sandbox Code Playgroud)

架构信息:

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

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

  • 能够在循环中使用其他表(插入,更新)枚举来自另一个表的选择,而无需从枚举的表中获取所有记录

我假设你要求这样的事情:

DB[:table].each do |row|
  DB[:other_table].insert(:blah=>row[:blah])
end
Run Code Online (Sandbox Code Playgroud)

由于连接池在插入on:other_table时使用相同的数据库连接,因此在Sequel中的某些适配器上无法正常工作,因为它仍然用于:select on table.您可以使用分片支持解决此问题:

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

在这种情况下,DB将使用:read_only shard用于select on:表,并使用:default default shard用于insert on:other_table.您还可以明确指定分片:

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

我没有提到的要点我假设你知道Sequel已经处理了.并且Sequel确实不能满足您的所有需求,但在这种情况下我怀疑任何其他ruby数据库库都会.