<?xml version="1.0" encoding="windows-1252"?>
<node id="700283" title="Perl ORM comparison (Class::DBI vs. DBIx::Class vs. Rose::DB::Object)" created="2008-07-26 05:13:37" updated="2008-07-26 01:13:37">
<type id="120">
perlmeditation</type>
<author id="694625">
aulusoy</author>
<data>
<field name="doctext">
&lt;p&gt;Hello all,&lt;/p&gt;

&lt;p&gt;
I have been looking at using a ORM for my next project and I came across [cpan://Class::DBI] and [cpan://DBIx::Class] on CPAN. 
&lt;/p&gt;

&lt;p&gt;
It would seem that [cpan://DBIx::Class] is a rewrite of [cpan://Class::DBI] with a growing user community. However, apart from talk that it "learned" from the lessons of [cpan://Class::DBI], I haven't found much information about why I should choose [cpan://DBIx::Class] over the other. 
&lt;/p&gt;

&lt;p&gt;UPDATE: And then there is [cpan://Rose::DB::Object], too.&lt;/p&gt;

&lt;p&gt;
I have read the documenation of all three modules, and am able to point out some differences. But what would be good is to have a complete comparison chart with pros/cons of each.
&lt;/p&gt;

&lt;p&gt;
I am starting a comparison in this thread with the little I know. I would be greatefull if you could add your input to this starter.
&lt;/p&gt;

&lt;p&gt;&lt;b&gt;UPDATE:&lt;/b&gt; Upon reading a reply to this thread, I am now putting [cpan://Rose::DB::Object] as one of the modules to be compared. The corresponding pros/cons are updated and enlarged too. &lt;p&gt;


&lt;h1&gt;Class::DBI&lt;/h1&gt;
&lt;readmore&gt;
&lt;h3&gt;Pros  (Class::DBI)&lt;/h3&gt;

&lt;li&gt;Mature and stable code (However, apparently with some unstabilities across versions, see below.)&lt;/li&gt;

&lt;li&gt;Good documentation. (IMHO)&lt;/li&gt;

&lt;li&gt;Ability to easily execute arbitrary SQL with &lt;code&gt;set_sql&lt;/code&gt; from the ancestor [cpan://Ima::DBI].&lt;/li&gt;

&lt;li&gt;Support for client-side triggers.&lt;/li&gt;

&lt;li&gt;Straightforward syntax for search (but less powerfull). &lt;/li&gt;

&lt;li&gt;Possibility to automagically and dynamically load metadata from an existing database following a certain non-customazible convention. (&lt;b&gt;is this true?&lt;/b&gt;)&lt;/li&gt; 

&lt;li&gt;Customizable column inflation/deflation.&lt;/li&gt;

&lt;li&gt;Seemingly, supports all databases supported by [cpan://DBI]  &lt;b&gt;(is this true?)&lt;/b&gt;&lt;/li&gt;

&lt;li&gt;Distinction of "primary/essential/other/all" column kinds. (Better for performance for large columns. However, [cpan://Class::DBI] is otherwise the worst performer apparently!)&lt;/li&gt;

&lt;li&gt;Supports UUID columns. (with a PlugIn).&lt;/li&gt;


&lt;h3&gt;Cons   (Class::DBI)&lt;/h3&gt;

&lt;li&gt;Seemingly shrinking user community.&lt;/li&gt;

&lt;li&gt;Single author =&gt; single point of failure&lt;/li&gt;

&lt;li&gt;Less frequent updates to the code.&lt;/li&gt;

&lt;li&gt;Less memory friendly.&lt;/li&gt;

&lt;li&gt;No support for in-memory-only objects&lt;/li&gt;

&lt;li&gt;Less powerfull search syntax (but simpler to use)&lt;/li&gt;

&lt;li&gt;No support for creating the database from class metadata &lt;b&gt;(is this true?)&lt;/b&gt;&lt;/li&gt;

&lt;li&gt;No built-in support for MANY-TO-MANY relations.&lt;/li&gt;

&lt;li&gt;No support for static class metadata generation.&lt;/li&gt;

&lt;li&gt;Doesn't really suport multiple existences od the same object on different databases, since the connection is setup from the object.&lt;/li&gt;

&lt;li&gt;Does NOt have seamless support for handy database &lt;i&gt;domains&lt;/i&gt; (production, test, dev, staging, ...) and &lt;i&gt;types&lt;/i&gt; (main, archive, reporting, ...).

&lt;/readmore&gt;


&lt;h1&gt;DBIx::Class&lt;/h1&gt;

&lt;readmore&gt;

&lt;h3&gt;Pros    (DBIx::Class)&lt;/h3&gt;

&lt;li&gt;Already large and growing user community&lt;/li&gt;

&lt;li&gt;Less preferable documentation. (IMHO)&lt;/li&gt;

&lt;li&gt;Memory friendly for large result sets.&lt;/li&gt;

&lt;li&gt;Ability to perform late execution of searches&lt;/li&gt;

&lt;li&gt;Ability to succesively narrow down the search by calling search multiple times on the ResultSet&lt;/li&gt;


&lt;li&gt;Possibility to automagically and dynamically load class metadata from an existing database following a certain non-customazible convention.&lt;/li&gt; 

&lt;li&gt;Possibility to create the database from class metadata albeit following non-customizable conventions.&lt;/li&gt;

&lt;li&gt;Seemingly, supports all databases supported by [cpan://DBI]  &lt;b&gt;(is this true?)&lt;/b&gt;&lt;/li&gt;

&lt;li&gt;Suports multiple existences od the same object on different databases, since the connection is setup from the schema.&lt;/li&gt;

&lt;li&gt;Supports UUID columns. (with a PlugIn).&lt;/li&gt;

&lt;li&gt;Support for MANY-TO-MANY relations. &lt;/li&gt;

&lt;li&gt;Support for &lt;i&gt;static&lt;/i&gt; class metadata generation&lt;/li&gt;


&lt;h3&gt;Cons   (DBIx::Class)&lt;/h3&gt;

&lt;li&gt;Relatively young code (since 2005) -- though, apparently, with a relatively stable interface. &lt;i&gt;&lt;b&gt;BUT&lt;/b&gt; the author states in the documentation that it may change any time!&lt;/i&gt;&lt;/li&gt;

&lt;li&gt;Multiple contributions =&gt; less coherence expected.&lt;/li&gt;

&lt;li&gt;Reproduces [cpan://Class::DBI] in many cases, although it claims to have learned from the lessons.&lt;/li&gt;

&lt;li&gt;No support for in-memory-only objects (just like [cpan://Class::DBI]&lt;/li&gt;

&lt;li&gt;No client-side triggers.&lt;/li&gt;

&lt;li&gt;Executing aribtrary SQL is more cumbersome (You have to set up a ResultSource for this. Note that executing arbitrary SQL may be considered by some as bad practise for an ORM.)&lt;/li&gt;

&lt;li&gt;The search syntax is quite complex and cumbersome.&lt;/li&gt;


&lt;li&gt;Does NOT have seamless support for handy database &lt;i&gt;domains&lt;/i&gt; (production, test, dev, staging, ...) and &lt;i&gt;types&lt;/i&gt; (main, archive, reporting, ...).




&lt;/readmore&gt;

&lt;h1&gt;Rose::DB::Object&lt;/h1&gt;

&lt;readmore&gt;

&lt;h3&gt;Pros   (Rose::DB::Object)&lt;/h3&gt;

&lt;li&gt;Single author =&gt; coherent interface&lt;/li&gt;

&lt;li&gt;Getting popular with a growing user base.&lt;/li&gt;

&lt;li&gt;Excellent documentation. (IMHO)&lt;/li&gt;

&lt;li&gt;Best performance (apparently)&lt;/li&gt;

&lt;li&gt;Support for in-memory-only objects.&lt;/li&gt;

&lt;li&gt;Memory friendly (if you choose it to be) with &lt;i&gt;real&lt;/i&gt; iterators that fetch data with the &lt;code&gt;next()&lt;/code&gt; call. &lt;/li&gt;

&lt;li&gt;Built-in support for MANY-TO-MANY relations.&lt;/li&gt;

&lt;li&gt;Possibility to automagically load metadata from an existing database following a certain -customazible- convention.&lt;/li&gt; 

&lt;li&gt;Support for static once-only generation of class metadata from an existing database for better performance and custamization (later, this is typically copied, pasted, and edited by the programmer.)&lt;/li&gt;

&lt;li&gt;Good balance of complexity, usefullness, and cumbersomeness of query syntax (IMHO)&lt;/li&gt;

&lt;li&gt;Supports inner and outer JOINS seamlessly in queries thanks to &lt;code&gt;require_objects&lt;/code&gt; and &lt;code&gt;with_objects&lt;/code&gt; constructs. &lt;/li&gt;

&lt;li&gt;Meaningful non-customizable defaults for column inflation/deflation. &lt;i&gt;For example DATE and TIMESTAMP columns get inflated into [cpan://DateTime] objects. Support for BOOL is there too.&lt;/i&gt;&lt;/li&gt;

&lt;li&gt;Lazy inflation/deflation of column values. (Good for performance.)&lt;/li&gt;

&lt;li&gt;Supports the innovative concepts of database &lt;i&gt;domain&lt;/i&gt;(production, test, dev, staging, ...) and database &lt;i&gt;type&lt;/i&gt; (main, arcvhive, reporting, ..). The actual &lt;i&gt;default&lt;/i&gt; database that is accessed by the application can be very easily and centrally modified. &lt;/li&gt;

&lt;li&gt;Suports multiple existences of the same object on different databases, since the connection is setup from the Rose::DB derived object.&lt;/li&gt;


&lt;h3&gt;Cons   (Rose::DB::Object)&lt;/h3&gt;

&lt;li&gt;Relatively young code (since 2005) -- though, apparently, with a relatively stable interface.&lt;/li&gt;

&lt;li&gt;Single author =&gt; single point of failure&lt;/li&gt;

&lt;li&gt;Only supports pg, MySQL, SQLite, and Informix for the moment. Oracle support is there but apparently not full.&lt;/li&gt;

&lt;li&gt;No support for creating the database from class metadata.&lt;/li&gt;

&lt;li&gt;Column inflation/deflation is not customizable but have relatively rich and meaningful defaults.&lt;/li&gt; 

&lt;li&gt;No client-side triggers. (but cascading deletes and loads are supported.)&lt;/li&gt;

&lt;li&gt;Executing arbitrary SQL is really hard to get at (need to use DBH directly) and there is no bridge between that SQL and the ORM.  &lt;b&gt;(is this true?)&lt;/b&gt; &lt;i&gt;Note that some consider executing raw SQL in an ORM as bad practise anyway. Besides [cpan://Rose::DB::Object] query syntax is rich enough (with joins and all) that you may not ever need it.&lt;/i&gt;&lt;/li&gt;

&lt;li&gt;No distinction for "primary/essential/other/all" column kinds except for primary key. (Maybe a performance issue for large columns. &lt;i&gt;However, apparently, [cpan://Rose::DB::Object] is otherwise the best performer.)&lt;/i&gt;&lt;/li&gt;

&lt;li&gt;No support for UUID columns.&lt;/li&gt;


&lt;/readmore&gt;


&lt;p/&gt;

&lt;p&gt;Please help making this comparison a more complete work with your knowledge!  Especially in those areas where it is marked "&lt;b&gt;is this true?&lt;/b&gt;".&lt;/p&gt;


&lt;p&gt;Perhaps I am missing some very obvious stuff.&lt;/p&gt;


&lt;b&gt;UPDATE:&lt;/b&gt;
&lt;h1&gt;CONCLUSION (TENTATIVE)&lt;/h1&gt;

&lt;p&gt;My humble conclusion, for the time being, is to go with [cpan://Rose::DB::Object].&lt;/p&gt;

&lt;p&gt;The reason behind this choice is the execellent documentation, seemingly coherent and well-thought-of interface, the good performnace (reported), the ability to use in-memory objects, and the clear and realtively concise query syntax. Though, not yet complete, [cpan://Rose::DB::Object] seems to be a good foundation ORM.&lt;/p&gt;

&lt;p&gt;For the moment, the only few downsides for me is the lack of [cpan://Catalyst] support, the shaky Oracle support, and the lack of UUID columns. I can deal with the [cpan://Catalyst] stuff as Catalyst does not require the Model to be really compliant, but I have to find an -elegant- way for the UUID columns. As for Oracle, I am gambling on the fact that the author will finish up the support before I need to use Oracle (My next project will be on Pg).&lt;/p&gt;

&lt;p&gt;One possible potential problem for the future may perhaps be the -&lt;i&gt;relative&lt;/i&gt;- difficulty of executing arbitrary SQL. One possible use is Pg full-text search (available since v8.3). This haunts me as it may not be easy to fix. &lt;b&gt;(Is this true?)&lt;/b&gt;&lt;/p&gt;





&lt;p&gt;Cheers&lt;/p&gt;
&lt;p&gt;Ayhan&lt;/p&gt;


















</field>
</data>
</node>
