Saturday, February 28, 2009

Sequel Models

In our last post here, we showed how we could use Sequel to create, access, and update a database with Ruby. In this post, we'll use Sequel models to do much the same thing. The nice thing about this is that we will be able to access our database using automatically generated ruby classes created from the database tables themselves. The code itself is very straightforward and I've commented it fairly completely. Here it is ...


require 'rubygems'
require 'sequel'

# Create an in-memory database
DB = Sequel.sqlite

# Create a new Country table with columns of
# id, name, and population.
DB.create_table :countries do
primary_key :id
column :name, :text, :unique=>true
column :population, :integer
end

# Create a Country model.
class Country < Sequel::Model; end

# Add some countries using our model. Note the id tag
# should get filed in automatically.
Country.create(:name => 'U.S.A.', :population => 250000000)
Country.create(:name => 'Mexico', :population => 251000000)
Country.create(:name => 'Canada', :population => 252000000)
Country.create(:name => 'France', :population => 300000000)

# U.S.A note the values are accessed as a hash of the column names.
usa = Country[:name => 'U.S.A.']
puts "USA: #{usa[:name]} #{usa[:population]}"

# or as attributes (should print the same as above).
puts "USA population: #{usa.name} #{usa.population}"

# Populations under (or equal to) 251 million
puts "Populations <= 251000000"
Country.filter(:population <= 251000000).each{|country| puts "Country #{country[:name]} #{country[:population]}" }

# Change the USA population (should print 100 more than the above).
usa.population = 250000100
puts "USA population: #{usa.name} #{usa.population}"

# Populations under (or equal to) 251 million. Note that U.S
# is not changed.
puts "Populations <= 251000000"
Country.filter(:population <= 251000000).each{|country| puts "Country #{country[:name]} #{country[:population]}" }

usa.update(:population => 250000200)
puts "USA: #{usa.name} #{usa.population}"

# Populations under (or equal to) 251 million
puts "Populations <= 251000000"
Country.filter(:population <= 251000000).each{|country| puts "Country #{country[:name]} #{country[:population]}" }

# Get the country with the ID of 3.
country = Country[3]
puts "Country 3 #{country[:name]} #{country[:population]}"

# Populations under (or equal to) 251 million
puts "Populations <= 251000000"
Country.filter(:population <= 251000000).each{|country| puts "Country #{country[:name]} #{country[:population]}" }



The one thing in all of this to note is that simply changing the model as we do in line 37 and print in 38 does not change the database backing as we can see by running our filter a few lines later. We need to use the update command as we do in line 45 before this will work. You can check out all the model based API here. Next we'll use a database model in Ramaze.

As always, let me know of any questions that you have.

2 comments:

  1. I think that you "meant" to write your expressions :population <= 251000000 as "population <= 251000000".

    ReplyDelete
    Replies
    1. Thanks, you are right. But why :population <= 251000000 does not work.
      According to http://sequel.jeremyevans.net/rdoc/classes/Sequel/Dataset.html#method-i-where, filter(:population <= 251000000) is correct.

      Delete