[Dbix-class] complex relationships I

Benjamin Hitz hitz at genome.stanford.edu
Thu Sep 20 19:32:20 GMT 2007


Hi, we are in the process of replacing an old, hand-rolled API (and  
bags-o-sql) with DBIc.  Our Oracle database is pretty large (~110  
tables) with some complicated relationships.  We have used  
DBIx::Class::Schema::Loader::Oracle to generate some table classes,  
but of course they don't find all the many-to-manys.

Looking for some advice on how to implement a couple types of  
relationships (This is long, so I will put the next one in another  
email)

"Trees" e.g.:
CREATE TABLE CV_TERM
(CV_TERM_NO NUMBER(10) NOT NULL
,CV_NO NUMBER(10) NOT NULL
,TERM_NAME VARCHAR2(1024) NOT NULL
,DBXREF_ID VARCHAR2(40)
,DATE_CREATED DATE DEFAULT SYSDATE NOT NULL
,CREATED_BY VARCHAR2(12) DEFAULT SUBSTR(USER,1,12) NOT NULL
,CVTERM_DEFINITION VARCHAR2(4000)
)
CREATE TABLE CVTERM_RELATIONSHIP
(CVTERM_RELATIONSHIP_NO NUMBER(10) NOT NULL
,CHILD_CV_TERM_NO NUMBER(10) NOT NULL
,PARENT_CV_TERM_NO NUMBER(10) NOT NULL
,RELATIONSHIP_TYPE VARCHAR2(40) NOT NULL
,DATE_CREATED DATE DEFAULT SYSDATE NOT NULL
,CREATED_BY VARCHAR2(12) DEFAULT SUBSTR(USER,1,12) NOT NULL
)
So CVTERM_RELATIONSHIP has two foreign keys to the CV_TERM table.

This comes out from Schema::Loader as:

In the Cv_term.pm module:

__PACKAGE__->has_many(
   "cvterm_relationship_child_cv_term_noes",
   "DB::Mod::Cvterm_relationship",
   { "foreign.child_cv_term_no" => "self.cv_term_no" },
);
__PACKAGE__->has_many(
   "cvterm_relationship_parent_cv_term_noes",
   "DB::Mod::Cvterm_relationship",
   { "foreign.parent_cv_term_no" => "self.cv_term_no" },
);

In the Cvterm_relationship.pm module:
__PACKAGE__->belongs_to(
   "child_cv_term_no",
   "DB::Mod::Cv_term",
   { cv_term_no => "child_cv_term_no" },
);
__PACKAGE__->belongs_to(
   "parent_cv_term_no",
   "DB::Mod::Cv_term",
   { cv_term_no => "parent_cv_term_no" },
);

So, I would guess I want to add:

__PACKAGE__->many_to_many (children =>  
'cvterm_relationship_child_cv_term_noes', 'child_cv_term_no');
and
__PACKAGE__->many_to_many (parents =>  
'cvterm_relationship_parent_cv_term_noes', 'parent_cv_term_no');

to Cv_term.pm

Of course, this is kinda silly because we don't really have multiple  
parents (but it is technically allowed in the schema).

So if I did something like:

my $CvTermObj = DBIx::Class::Schema::Subclass->schema->resultset 
('CV_TERM')->find({term_name => 'physical interactions'});
(actually not sure if find returns a single object in scalar context,  
but that's a detail)

my @arrayOfChildrenWhichAreAlsoCvTermObjs = $cvTermObj->children();

That didn't seem so bad... maybe the next one is tougher?

Ben


--
Ben Hitz
Senior Scientific Programmer ** Saccharomyces Genome Database ** GO  
Consortium
Stanford University ** hitz at genome.stanford.edu






More information about the DBIx-Class mailing list