gpt4 book ai didi

ruby - ruby 的数据库抽象/适配器

转载 作者:数据小太阳 更新时间:2023-10-29 07:54:28 28 4
gpt4 key购买 nike

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

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

我最感兴趣的是:

  • 简单、干净且没有歧义的 API
  • 数据选择(显然)、过滤和聚合
  • 原始值选择没有字段映射:SELECT col1, col2, col3 => [val1, val2, val3] not hash of { :col1 => val1 ...}
  • 能够传递要选择的列/值的列表:select(array_of_columns)(不是:dataset.select(:col1, :col2, :col3),它要求列是已知的)
  • API 以一致(且有效)的方式考虑表模式“some_schema.some_table”;也对此进行反射(reflection)(从表中获取模式)
  • 数据库反射:获取表列的列表、它们的数据库存储类型以及适配器的抽象类型
  • 表的创建、删除
  • 能够在循环中使用其他表(插入、更新)从另一个表中枚举选择,而无需从被枚举的表中获取所有记录

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

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

最佳答案

我是 Sequel 的首席开发人员,所以这个回答显然有偏见,但我不知道有任何 ruby​​ 数据库库可以满足您的所有需求。

似乎您的一些愿望在 Sequel 中被认为是局限性,其中一些可以解决:

  • 没有字段映射的原始值选择:SELECT col1, col2, col3 => [val1, val2, val3] not hash of { :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 是微不足道的:

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

尝试:

array_of_columns = [:col1, :col2, :col3]
DB[:table].select(*array_of_columns)
# SELECT col1, col2, col3 FROM table
  • API 以一致(且有效)的方式考虑表模式“some_schema.some_table”;也对此进行反射(reflection)(从表中获取模式)

续集处理表模式:

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

任何这不起作用的地方通常被认为是一个错误。我不确定你所说的反射(reflection)是什么意思。同一个表名可以在多个模式中使用,所以一个表在哪个模式中通常是一个模棱两可的问题。

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

作为符号数组的列:

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

架构信息:

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

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

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

我假设你要求的是这样的:

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

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

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

在这种情况下,DB 将使用 :read_only 分片在 :table 上进行选择,并使用 :default 分片在 :other_table 上进行插入。您还可以明确指定分片:

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

我没有提到的要点我假设你知道 Sequel 已经处理了。当然,Sequel 可能无法满足您的所有需求,但在这种情况下,我怀疑任何其他 ruby​​ 数据库库都无法满足。

关于ruby - ruby 的数据库抽象/适配器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2942663/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com