http://www.perlmonks.org?node_id=968544


in reply to Re: Search for ORM with Multi-Table-Object Support
in thread Search for ORM with Multi-Table-Object Support

Thanks for your answer,

I am not sure if you mean the same as I do, when refering to Multi-Table-Mapping-Objects.

I mean an object, which consists of one row out of one table and another one out of another table.

What I would wish to do is

# Tablesetup: [user] id username password [user_contact] id firstname lastname street zip city phone [user_profile] id profile_text profile_image # Code-Example $user->load({id => 1, fetch => qw('username firstname lastname')}); print $user->firstname; # prints prefetched firstname print $user->lastname; # prints prefetched lastname print $user->profile_text; # prints lazy-loaded profile_text

As I understand DBIC I would do the following (ignoring lazy-loading):

$user = $schema->resultset('User')->find(1); print $user->user_contact->firstname; print $user->user_contact->lastname; print $user->user_profile->profile_text;

Well, of course I could get around this limitation by writing my own setters and getters accessing the sub-objects from within the parent-object. Maybe this is the best way to do it, but I tought there may be ORMs which can handle this behavior already.

Regards
Alex

Replies are listed 'Best First'.
Re^3: Search for ORM with Multi-Table-Object Support
by Your Mother (Archbishop) on May 03, 2012 at 00:52 UTC

    It might just be personal bias but that feels messy compared to the affordance it gives. You could potentially do the same thing with Moose using handles on the foreign objects attributes. That seems like a mistaken can of worms and a performance ding though… As you mentioned, you could write your own shortcut routines and you could make it semi-lazy with has_column_loaded.

    There are two natural ways you can do some of what you want in DBIC. The first is keeping the DB in line with the code: a VIEW. This is mysql syntax–

    CREATE VIEW uview AS SELECT u.id ,u.username ,c.name ,c.address ,p.text ,p.image FROM user u ,contact c ,profile p WHERE c.user = u.id AND p.user = u.id ;

    And then you create a regular DBIC result class for it. I tried a loader with dbicdump and it seems to work just fine.

    Alternatively you could do a DBIC in-code view class. With __PACKAGE__->result_source_instance->is_virtual(1) and the same SQL as the result_source_instance->view_definition. Both of these suffer from returning readonly objects and the real VIEW additionally will likely create real, and ultimately useless/confusing, tables upon deployment while the in-code view will not. (Update: it occurs to me that could put the is_virtual on the real VIEW too to keep it from creating a new table on $schema->deploy… but I didn't test and it's not put in by the loader/dumper defaults.)

    But for convenience and a sort of permanent join/prefetch this would do what you want (as long as you only want to read).

Re^3: Search for ORM with Multi-Table-Object Support
by preaction (Beadle) on May 02, 2012 at 22:46 UTC
    DBIC is simpler than SQLAlchemy, so it doesn't do this kind of thing for you. Personally, I like the obvious separation of the objects: It makes the data model and relationships more apparent from the code (though I would remove the user_ prefix from the relationships). I've rarely had all of my code (DBIC or SQLAlchemy) survive database schema changes, unless I had planned for that schema to change (simple adding/removing optional columns for example).
      Personally, I like the obvious separation of the objects: It makes the data model and relationships more apparent from the code

      Sure - I'd have said something alike two years ago, too.

      But today I have to deal with a complex database structure, which is build out of at least 400 tables per Project-DB (with somewhat around 30 project DBs most of which have "nearly" identical structures) which has historically grown and is messy like hell. And it is my job to change that, make the database perform better, be more flexible and stuff - with nearly no man power to change the querys in the constantly growing and changing application.

      Starting with an ORM opens the door for constantly changing access from pure sql to an object oriented way and when this is done I wish to be able to change objects and database together without the need to let the app or the developers change the way they work. I belive this only to be possible if objects are not to closely linked to the data model and relations.

      So please understand that I have no room for "It's nicer if the objects line up nicely with the data-model"-Stuff. Yes it surely is, you are perfectly right, but I don't need it nice, I just need it working and changeable without to great effort.

Re^3: Search for ORM with Multi-Table-Object Support
by trwww (Priest) on May 03, 2012 at 04:56 UTC

    DBIx::Class certainly has what you are asking for with has_one, and combining Subset_of_related_fields and Incomplete_related_objects.

    I'd put together an example for you but its all right there.

    Also, you didn't mention you'd be doing updates, as mentioned elsewhere I believe a view would make the most sense.