[Dbix-class] For a reliable update_or_create we need to make create( { primary_key => undef, ... } ) work in Pg

Zbigniew Lukasiak zzbbyy at gmail.com
Fri Jan 18 12:05:30 GMT 2008


I think I have it well documented in the "rs->find finds by all
columns" thread that find behaviour is rather not reliable when it is
not fed a unique constraint.  By the way here is another question -
what should happen when you call find with just one of the two fields
in a composed primary key?  Currently it would return just first
record with that one field set to the searched value, I don't know if
that is a bug - but it is surprising isn't it?

In fact all of this is not that bad - because it can also be viewed as
an error on the application side to try to find something without
supplying a unique condition.

The problem is that update_or_create relies on calling find without a
unique constraint.  And more precisely it needs to do that if you want
to write a generic handler for updating or creating rows that would
work for all databases.  The reason for that is that $rs->create( {
primary_key => undef, ... } ) will not work for Pg so when you call
update_or_create and you have no primary key you need to delete it
from the query.  A workaround for this would be to delete the
primary_keys from the query if they are set to 'undef' in the create
method (or just in the Pg driver).  The additional benefit of that
would be that it would make DBIx::Class more database independent
(create( {primary_key => undef, ... }) works in MySQL and SQLite - so
it should work in Pg also, or we should make it an error across all
the databases).

-- 
Zbigniew Lukasiak
http://perlalchemy.blogspot.com/

PS Here is the test for find on a composed key:

my $twokeys = $schema->resultset("TwoKeys")->first;
ok( $twokeys, 'Twokeys found' );
my $another_twokeys = $schema->resultset("TwoKeys")->find( { cd =>
$twokeys->cd->cdid } );
ok( ! $another_twokeys, 'No twokeys found by just part of the primary
key' );my $cd = $schema->resultset("CD")->first;



More information about the DBIx-Class mailing list