What is the correct way to setup database with DataMapper and Sinatra on production server?
Asked Answered
S

1

13

From the DataMapper document, I think there are at least four functions need to be called to have database setup:

DataMapper.setup(:default, 'sqlite:///path/to/project.db')
DataMapper.finalize
DataMapper.auto_migrate!
DataMapper.auto_upgrade!

In many DataMapper+Sinatra tutorials I learned that auto_migrate! and auto_upgrade! are not supposed to be called every time the app is loaded on production server. But in the meanwhile many examples call these functions in the main ruby file of the sinatra app, say app.rb, without additional check. And some examples do not call finalize at all. So far I am confused and I am not sure what to do on the production server.

Take this following simple app.rb for example, I have some questions:

  1. Where and when should finalize be called?
  2. When deploying the app first time there is no db file on the production server, how do I have it automatically created? Or do I have to create the project.db file manually?
  3. Since the auto_upgrade! is wrapped in :development block, it won't be called on production server. How am I supposed to upgrade database when I add or remove columns in it?
require 'sinatra'
require 'data_mapper'

configure do
  DataMapper.setup :default, "sqlite3://#{Dir.pwd}/project.db"
end

class Book
  include DataMapper::Resource
  property :id, Serial
  property :title, Text

  belongs_to :author
end

class Author
  include DataMapper::Resource
  property :id, Serial
  property :name, Text

  has n, :books
end

configure :development do
  DataMapper.auto_upgrade!
end

get '/:id' do
  @author = Author.get params[:id]
  erb :list_author_and_his_books # The template has nothing to do with this question, ignore it
end

get '/new' do
  # Some code for user to input book or author details
end

get '/create' do
  # Some code to create book or author in db
end

Thanks for reading this long post :D

Sagamore answered 2/5, 2013 at 8:19 Comment(0)
M
7

Where and when should finalize be called?

From http://rdoc.info/github/datamapper/dm-core/DataMapper#finalize-class_method

This method should be called after loading all models and plugins.

When deploying the app first time there is no db file on the production server, how do I have it automatically created? Or do I have to create the project.db file manually?

It depends on your hosting arrangement, but the main thing to do is put the running of migrations in a Rake task and run them when the app is deployed. If you're using Sqlite, this would create the database (although on some hosts you are not allowed to update the file system). I don't think it's a good idea to use Sqlite for a production database, but that's your decision.

Since the auto_upgrade! is wrapped in :development block, it won't be called on production server. How am I supposed to upgrade database when I add or remove columns in it?

Use a Rake task. After each deployment you'd run the "db:migrate:up" (or whatever you'd called it) task and it would run the latest migrations. You might get a few ideas from Padrino's Rake tasks for DataMapper

Morgue answered 2/5, 2013 at 13:25 Comment(2)
Thanks @iain, sqlite3 will be replaced in the future! Do you think it's better to separate database definition from the main app.rb and run the migration or upgrade explicitly with a task?Sagamore
@hsw It's up to you. I tend to put models in app/models and migrations in db/migrations. On deploy I'll run a rake task that runs the migrations. The models I require in the config.ru (or usually an init file, since settings will grow, grow, grow!:) before the main app file. BTW, I found this, it should be much more helpful. Have a look at this question for ideas on how to layout your app. It's up to you though, it's Sinatra.Morgue

© 2022 - 2024 — McMap. All rights reserved.