unix_hacker_beard has asked for the wisdom of the Perl Monks concerning the following question:

Gracious Monks,

I am using Class::DBI to represent my database in Perl. I want my application to support interchangeable databases using the DBD adapters (aside from RAM). Class::DBI is a wonderful way to achieve this as far as representation but in the documentation it says "Class::DBI works on a simple one class/one table model. It is your responsibility to have your database tables already set up. Automating that process is outside the scope of Class::DBI".

Is there a preferred module to use alongside Class::DBI to handle creation responsibilities?

  • Comment on Database-independent means of creating database?

Replies are listed 'Best First'.
Re: Database-independent means of creating database?
by Your Mother (Archbishop) on Jan 25, 2011 at 15:54 UTC

    DBIx::Class::Schema->deploy can do this. You write -- or can automatically generate with DBIx::Class::Schema::Loader's make_schema_at if you have a DB already -- your DBIC schema. Then you can deploy it to (most) any DB by providing a valid/permissive connection.

    There are caveats and edge cases because DBs can be customized so much; read the docs thoroughly.

    Class::DBI might have similar functionality now, it didn't in the past. I used it a lot for a couple of years but haven't gone back since DBIC matured.

      Great! This seems to be what I was looking for!
      This is working great and is successfully creating my database from the provided schema but is there a way to make sure the database doesn't exist before calling deploy? I tried checking $@ after calling deploy inside an eval but it stays empty. If I'm using SQLite I can check if -e but I'd rather not be limited to any certain database...

        I think there is probably a better way—and I’d like to know one but don’t have time to code dive, play—but this kind of thing should work.

        use warnings; no warnings "uninitialized"; use strict; use MyApp::Schema; my $schema = MyApp::Schema->connect("dbi:SQLite::memory:"); my ( $first_source ) = $schema->sources; my $ok = eval { $schema->resultset($first_source)->count || 1; }; if ( $@ =~ /no such table/ ) { warn $@; print "Trying to deploy...\n"; $schema->deploy; $schema->resultset($first_source)->count; print "Deploy seems good!\n"; } elsif ( not $ok ) { die $@ || "Uh... something bad, something, something\n"; }
Re: Database-independent means of creating database?
by Corion (Patriarch) on Jan 25, 2011 at 15:36 UTC

    Personally, I use (disclaimer: my own) DBIx::RunSQL to set up my databases from Perl. This makes it especially convenient for creating throwaway test databases for the regression tests.

    As Class::DBI loads most of the information about fields from the database, you'll need to store the field definition somewhere. I find SQL a good Data Definition Language.

Re: Database-independent means of creating database?
by JavaFan (Canon) on Jan 25, 2011 at 19:22 UTC
    I am using Class::DBI to represent my database in Perl.
    Oh dear.

    Why?

    Note that Class::DBI does quite the opposite of what most people think it does. It doesn't provide an encapsulation layer for the database. In fact, it exposes tables as classes.

    Not that other ORM are any better. See The Vietnam Of Computer Science. Or the short version.

      I agree with Ted completely; there is no good solution to the object/relational mapping problem. There are solutions, sure, but they all involve serious, painful tradeoffs.

      What do you see as the serious and painful tradeoffs of ORMs in Perl?