Question

When I run this code

require 'rubygems'
require 'data_mapper'
require "sqlite3"

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}./prod.db")

class Person
  include DataMapper::Resource
  property :id, Serial

  def initialize(name)
    self[:name] = name
    self.save!
  end

end

DataMapper.finalize.auto_migrate!

This error gets thrown

DataObjects::ConnectionError: unable to open database file (code: 14, sql state: , query: , uri: ).

It seems to be complaining about the DataMapper.finalize.auto_migrate! line.

If I comment out the person class, the code runs fine, albeit, somewhat uselessly.

The OS I am getting the error on is Linux Mageia 2. I have run this fine on WindowsXP and Windows7 both running Ruby 1.9.3, though I suspect that the issue is the older ruby version is the issue not the OS.

Also, it is probably important for me to tell you that the permissions on the folder containing the file is very open (-rwxrwxrwx) (Its probably not practical for it to be this open for everyday use, but am desperate to get data_mapper working).

Here are other specs that may be interesting My local gems sqlite3 (1.3.7, 1.3.3) sqlite3-ruby (1.3.3) data_mapper (1.2.0)

I understand there are a lot of variables in here that could be changed. I thought I would put this out there first and see whether it was simple fix that I was dunderheadedly missing :)

Was it helpful?

Solution

In your code you have DataMapper setup instruction

DataMapper::setup(:default, "sqlite3://#{Dir.pwd}./prod.db")

which tells that the sqlite database-file location is in a directory named: current working directory + ., which cannot be found and hence the error. So removing the dot from the URI should resolve your problem for that part.

Note that #{Dir.pwd} points to the current working directory; it might be safer to point to the absolute path, in relation to the current file, by instead saying – for example: File.dirname(File.expand_path(__FILE__)). The reason is that if the file is used outside the directory it exists in, it can be found.

Now for the class definition. In your initialization you reference a non-existing method/property called name. I think what you are looking for is just a property declaration, such as

property :name, String

You don’t need an initializer for that, you can just use, for example, Person.create(:name => 'Foo') which persists the object into the database.

Speaking of which, coming back to the default database connection, you might be interested using an in-memory sqlite for testing. You can do this by

DataMapper.setup(:default, "sqlite::memory:')

This will start the db from a clean slate every time you use the file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top