Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: Class::DBI vs. DBIx::Class

by rafl (Friar)
on Jun 25, 2006 at 11:16 UTC ( [id://557422]=note: print w/replies, xml ) Need Help??


in reply to Class::DBI vs. DBIx::Class

I strongly suggest using DBIx::Class.

It learned a lot from the mistakes Class::DBI made and also has a vast amount of features Class::DBI doesn't have.

My favourite is the concept of ResultSets. For example can put together your queries piece by piece:

my $persons = $schema->resultset('Person'); my $active_persons = $person->search({ active => 1 });

Now you can either iterate over the results of those two resultset..

while (my $person = $person->next) { ...; }

.. or get a list of objects, representing rows, back..

my @person_objs = $person->all;

.. or do further searches..

$active_persons->search({ writeup_comment.title => 'Foo', }, { join => { writeup => 'writeup_comment' }, prefetch => 'writeup', }); # gets you all persons with have recieved a comment with the title 'Fo +o' for one of their writeups, for example

.. or do a related_searche to get a resultset associated with another table or view, which are somehow connected to the current resultset:

my $writeups = $active_persons->search_related('Writeup');

Note that SQL statements are only executed when it's actually needed, which makes DBIx::Class quite performant.

Even if DBIx::Class still misses some features one might expect (subqueries, triggers, ...) I think it's already quite stable and I use it for production in several places.

Cheers, Flo

Replies are listed 'Best First'.
Re^2: Class::DBI vs. DBIx::Class
by hrr (Monk) on Jun 25, 2006 at 14:46 UTC
    Now I understand that DBIx::Class is more flexible than Class::DBI! On the other hand, this comes at the price of longer code for simple tasks, e.g., for inserting into a table 'Person', one would use
    # using DBIx::Class: $schema->resultset('Person')->new({FirstName=>'Joe'})->insert(); # using Class::DBI: DB::Person->insert({FirstName=>'Joe'});
    Nevertheless, the greater flexibility motivated me to try DBIx::Class, too. What still bothers me is that
    package DB::Person; use base 'DBIx::Class'; __PACKAGE__->load_components(qw/PK::Auto Core/); __PACKAGE__->table('T_PERSON'); __PACKAGE__->add_columns(qw[PersonId FirstName]); __PACKAGE__->set_primary_key('PersonId'); package DB; use base 'DBIx::Class::Schema'; __PACKAGE__->load_classes(qw[Person]);
    fails with Can't locate object method "result_source_instance" via package "DB/Person" (perhaps you forgot to load "DB/Person"?) at c:/Perl/site/lib/DBIx/Class/Schema.pm line 75. If I put the definition of DB::Person into DB/Person.pm, it works, but is far less elegant/compact. Is there a smarter solution?
      On the other hand, this comes at the price of longer code for simple tasks, e.g., for inserting into a table 'Person', one would use
      # using DBIx::Class: $schema->resultset('Person')->new({FirstName=>'Joe'})->insert(); # using Class::DBI: DB::Person->insert({FirstName=>'Joe'});

      How about:

      $schema->resultset('Person')->create({ FirstName => 'Joe' });

      If you don't want to get the resultset from the schema first, you'll need to use DBIx::Class (DBIC) without a schema, which is usually called CDBI plain, but you'll then loose the advantages of the composable schemas, which, for example, allow you to connect to multiple databases from the same set of classes. I think using schemas is usually worth the overhead.

      I don't really know how to solve your problem with the posted snippet, but I suspect it's caused by the load_classes call. You can probably work that around with using register_class or register_source, but I haven't really looked into that as I don't like to ram up a single .pm file with several modules.

      Cheers, Flo

        Thank you very much! register_class works well:
        package DB; map { __PACKAGE__->register_class($_, __PACKAGE__ . "::$_") } qw(Perso +n);
        Actually, connecting to single database is sufficient for me in most of the cases, so working without a schema would be great. How would I do this concretely? It did not find it in the documentation---apparently, working with a single database is (surprisingly) not very popular. Would I need to declare DB::Person as a subclass of ResultSource?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://557422]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (5)
As of 2024-03-19 08:46 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found