Reputation: 2097
What are the database abstractions/adapters you are using in Ruby? I am mainly interested in data oriented features, not in those with object mapping (like active record or data mapper).
I am currently using Sequel. Are there any other options?
I am mostly interested in:
Purpose is to manipulate data with unknown structure at the time of writing code, which is the opposite to object mapping where structure or most of the structure is usually well known. I do not need the object mapping overhead.
What are the options, including back-ends for object-mapping libraries?
Upvotes: 3
Views: 1119
Reputation: 12139
I'm the lead developer of Sequel, so this response is obviously biased, but I'm not aware of any ruby database library that does everything you want.
It appears that some of your desires are perceived limitations in Sequel, some of which can be addressed:
Try:
DB[:table].filter([:col1, :col2, :col3].zip([1, 2, 3]))
# SELECT * FROM table WHERE ((col1 = 1) AND (col2 = 2) AND (col3 = 3))
It's trivial to add a new dataset method that provides a nicer API for the above:
DB[:table].bfilter([:col1, :col2, :col3], [1, 2, 3])
Try:
array_of_columns = [:col1, :col2, :col3]
DB[:table].select(*array_of_columns)
# SELECT col1, col2, col3 FROM table
Sequel deals with table schemas:
DB[:schema__table]
DB[:table.qualify(:schema)]
# SELECT * FROM schema.table
Any place where this doesn't work is generally considered a bug. I'm not sure what you mean by reflection. The same table name can be used in multiple schemas, so which schema a table is in is generally an ambiguous question.
Columns as array of symbols:
DB[:table].columns
# => [:col1, :col2, :col3]
Schema information:
DB.schema(:table)
# [[:col1=>{:type=>:integer, :db_type=>'int(11)', :default=>nil, ...}], ...]
:type is the ruby type symbol, :db_type is the database type string.
I assume you are asking for something like this:
DB[:table].each do |row|
DB[:other_table].insert(:blah=>row[:blah])
end
Which doesn't work correctly on some adapters in Sequel due to the connection pool using the same database connection for the insert on :other_table while it is still being used for the :select on table. You can work around this by using the sharding support:
DB = Sequel.connect(..., :servers=>{:read_only=>{}})
DB[:table].each do |row|
DB[:other_table].insert(:blah=>row[:blah])
end
In this case, DB will use the :read_only shard for the select on :table and the :default shard for the insert on :other_table. You can also specify shards explicitly:
DB[:table].server(:read_only).each do |row|
DB[:other_table].server(:default).insert(:blah=>row[:blah])
end
The points I didn't address I assume you know that Sequel already handles. And it's certainly possible that Sequel doesn't meet all of your needs, though in that case I doubt any other ruby database library will.
Upvotes: 5