[Dbix-class] Is there a better way to handle inserts with multi column primary keys?

John Napiorkowski jjn1056 at yahoo.com
Tue May 2 19:50:56 CEST 2006


Turns out a more careful reading of the documentation
could answer this question.  All the '->find(xx)'s
where not needed.  If the schemas are properly written
 using 'belong_to' and 'has_many' then I could just
say (from the lower example):

my $schema = DB::Main->connect(...);
my $doc = $schema->resultset('documents')->find(1);

my $paras = $doc->paragraphs;

and get an iterator that works the way I wanted.  When
I get a change I will write a clarification posting so
that other newbies like me can understand (hopefully)
the 'DBIx way'.

--john

--- John Napiorkowski <jjn1056 at yahoo.com> wrote:

> This is a question about multi column relationships.
> 
> Let's say you have two tables like this in postgres.
> 
> The first table is a list of document titles and the
> second is a list of the titles for paragraphs in a
> given document:
> 
> create table documents (
>  document_id serial not null,
>  title varchar(24) not null,
>  constraint PRIMARY KEY (document_id)
> );
> 
> create table paragraphs (
>  paragraph_id serial not null,
>  document_id int not null,
>  title varchar(24) not null,
>  constraint PRIMARY KEY (paragraph_id, document_id),
>  constraint FORIEGN KEY (document_id) REFERENCES
> documents(document_id)
> );
> 
> and in table documents you have
> 
> document_id, title
> 1, "First Document"
> 2, "Second Document"
> 
> and in table paragraphs you have
> 
> document_id, paragraph_id, title
> 10, 1, "First Paragraph in First Document"
> 10, 2, "Second Paragraph in First Document"
> 11, 1, "First Paragraph in SecondDocument"
> 
> Now if I set up my DBIx schemas properly I can
> access
> the paragraphs through documents like so:
> 
> my $schema = DB::Main->connect(...);
> my $doc = $schema->resultset('paragraphs')->find(1);
> my $para = $doc->paragraphs->find({document_id=>1,
> paragraph_id=>1});
> 
> Basically this works, but I was wondering if there
> is
> a way to avoid repeating the document_id in the
> second
> find.  I am thinking this is possible because the
> $doc
> object knows it's own primary_key.  In fact when I
> turn on sql debugging to see what SQL is generated I
> see something like:
> 
>     -> prepare_cached for DBD::Pg::db
> (DBI::db=HASH(0x9a34824)~0x9a35574 'SELECT
> pa.paragraph_id, pa.document_id, pa.title FROM
> paragraphs pa me WHERE ( ( ( pa.document_id = ? AND
> pa.paragraph_id = ? ) AND ( pa.document_id = ? ) )
> )'
> HASH(0x9a503a8) 3) thr#814c008
> 
> So I can see that DBIx is repeating the contraint
> for
> document_id twice, thus is is smart enough to know
> that to properly do a find it needs to do this.
> 
> So I though I could just try:
> 
> my $para =
> $doc->paragraphs->find({paragraph_id=>1});
> 
> or even:
> 
> my $para = $doc->paragraphs->find(1);
> 
> But both give me errors.
> 
> Although it works in the example above, I'd like to
> find out if there is a way I can simplify my syntax
> and avoid repeating the second document_id.  I think
> the ideal syntax would be something like:
> 
> my $para =
> $doc->paragraphs->find({paragraph_id=>1});
> 
> or something like it.  Does anyone have experience
> with this?  If there is no way to do this and other
> people think it's a good idea I'd like to work on a
> patch to provide it.
> 
> Thanks for your insight.
> 
> --john
> 
> 
> 
> 
> 
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam
> protection around 
> http://mail.yahoo.com 
> 
> _______________________________________________
> List:
>
http://lists.rawmode.org/cgi-bin/mailman/listinfo/dbix-class
> Wiki: http://dbix-class.shadowcatsystems.co.uk/
> IRC: irc.perl.org#dbix-class
> SVN:
>
http://dev.catalyst.perl.org/repos/bast/trunk/DBIx-Class/
> 


__________________________________________________
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 



More information about the Dbix-class mailing list