Deployment without cascading updates/deletes

8 messages Options
Embed this post
Permalink
Will Hawes

Deployment without cascading updates/deletes

Reply Threaded More More options
Print post
Permalink
While deploying a schema to a SQL Server 2005 database today I ran
into this database error:

Msg 1785, Level 16, State 0, Line 1236
Introducing FOREIGN KEY constraint 'tblItemCategory_fk_item_id' on
table 'tblItemCategory' may cause cycles or multiple cascade paths.
Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other
FOREIGN KEY constraints.
Msg 1750, Level 16, State 0, Line 1236
Could not create constraint. See previous errors.

OK, so the workaround is to switch off cascading for the constraints
in question. I had a look at the docs for DBIx::Class::Relationship,
which state:

"Cascading deletes are off by default on a belongs_to relationship. To
turn them on, pass cascade_delete => 1 in the $attr hashref."

The default behaviour is not as documented - I had not specified any
cascade behaviour for the constraint. Setting cascade_delete => 0 or
cascade_delete => undef had no effect on the generated SQL, which
still contained "ON DELETE CASCADE ON UPDATE CASCADE".

The relevant source code in SQL::Translator::Parser::DBIx::Class
appears to be this:

my $cascade;
for my $c (qw/delete update/) {
    if (exists $rel_info->{attrs}{"on_$c"}) {
        if ($fk_constraint) {
            $cascade->{$c} = $rel_info->{attrs}{"on_$c"};
        }
        else {
            carp "SQLT attribute 'on_$c' was supplied for relationship
'$moniker/$rel', which does not appear to be a foreign constraint. "
            . "If you are sure that SQLT must generate a constraint
for this relationship, add 'is_foreign_key_constraint => 1' to the
attributes.\n";
        }
    }
    elsif (defined $otherrelationship and
$otherrelationship->{attrs}{$c eq 'update' ? 'cascade_copy' :
'cascade_delete'}) {
        $cascade->{$c} = 'CASCADE';
    }
}

It looks like the user needs to use on_update and on_delete to specify
exactly what they want the constraint to do, rather than supplying a
true/false value to cascade_update/cascade_delete (which look as
though they might be deprecated?). This worked for me - I defined {
on_delete => 'NO ACTION', on_update => 'NO ACTION' } in the relevant
belongs_to relation and got the expected SQL.

I'm guessing this is just a case of slightly outdated doc in
DBIx::Class::Relationship - can someone in the know confirm either way
please? Happy to patch if required.

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Benjamin Hitz

Resultset chaining

Reply Threaded More More options
Print post
Permalink

I am having trouble chaining result sets; that is running ->search  
subsequently.
So then I tried this:

(with DBIC_TRACE =1)

DB::Mod ISA DBIx::Class::Schema

fasolt 140 > perl -I./ -MDB::Mod -e
'$r=DB::Mod->schema->resultset("Feature"); \
$r->search(gene_name=>"ACT1");\
$r->all' ;
SELECT me.feature_no, me.taxon_id, me.dbxref_id, me.feature_name,  
me.feature_type, me.source, me.status, me.gene_name, me.date_created,  
me.created_by FROM BUD.feature me:


fasolt 141 > perl -I./ -MDB::Mod -e
'$r=DB::Mod->schema->resultset("Feature")->search(gene_name=>"ACT1");\
$r->all' ;
SELECT me.feature_no, me.taxon_id, me.dbxref_id, me.feature_name,  
me.feature_type, me.source, me.status, me.gene_name, me.date_created,  
me.created_by FROM BUD.feature me WHERE ( gene_name = ? ): 'ACT1'

Why does the first one give me different SQL?
My DBIx::Class version is 0.08111
My SQL::Abstract version is 1.58

Thanks,
Ben
--
Ben Hitz
Senior Scientific Programmer ** Saccharomyces Genome Database ** GO  
Consortium
Stanford University ** [hidden email]




_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Rob Kinyon

Re: Resultset chaining

Reply Threaded More More options
Print post
Permalink
On Wed, Oct 14, 2009 at 16:39, Benjamin Hitz <[hidden email]> wrote:
>
> I am having trouble chaining result sets; that is running ->search
> subsequently.
> So then I tried this:

[snip] Neither will work because you aren't passing hashrefs.

--
Thanks,
Rob Kinyon

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Benjamin Hitz

Re: Resultset chaining

Reply Threaded More More options
Print post
Permalink

Oooh... nice catch but the second one succeeds; that is the correct SQL.

And this still fails to add the where clause
perl -I./ -MDB::Mod -e '$r=DB::Mod->schema->resultset("Feature"); $r-
 >search({gene_name=>"ACT1"});$r->all' ;


Ben
On Oct 14, 2009, at 1:46 PM, Rob Kinyon wrote:

> On Wed, Oct 14, 2009 at 16:39, Benjamin Hitz  
> <[hidden email]> wrote:
>>
>> I am having trouble chaining result sets; that is running ->search
>> subsequently.
>> So then I tried this:
>
> [snip] Neither will work because you aren't passing hashrefs.
>
> --
> Thanks,
> Rob Kinyon
>
> _______________________________________________
> List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
> IRC: irc.perl.org#dbix-class
> SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
> Searchable Archive: http://www.grokbase.com/group/dbix-class@...

--
Ben Hitz
Senior Scientific Programmer
Saccharomyces Genome Project
Stanford University
[hidden email]




_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Rob Kinyon

Re: Resultset chaining

Reply Threaded More More options
Print post
Permalink
On Wed, Oct 14, 2009 at 16:53, Benjamin Hitz <[hidden email]> wrote:
>
> Oooh... nice catch but the second one succeeds; that is the correct SQL.
>
> And this still fails to add the where clause
> perl -I./ -MDB::Mod -e '$r=DB::Mod->schema->resultset("Feature");
> $r->search({gene_name=>"ACT1"});$r->all' ;

->search returns the new resultset. It does NOT modify the invocant.

$r = $r->search( ... );

Rob

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
John Romkey

Re: Resultset chaining

Reply Threaded More More options
Print post
Permalink
In reply to this post by Benjamin Hitz


On Wed, Oct 14, 2009 at 4:53 PM, Benjamin Hitz <[hidden email]> wrote:


On Oct 14, 2009, at 1:46 PM, Rob Kinyon wrote:

On Wed, Oct 14, 2009 at 16:39, Benjamin Hitz <[hidden email]> wrote:

I am having trouble chaining result sets; that is running ->search
subsequently.
So then I tried this:

[snip] Neither will work because you aren't passing hashrefs.


| Oooh... nice catch but the second one succeeds; that is the correct SQL.
|
| And this still fails to add the where clause
|
| perl -I./ -MDB::Mod -e '$r=DB::Mod->schema->resultset("Feature"); $r->search({gene_name=>"ACT1"});$r->all' ;
|
|
| BenĀ 

That's because you're not chaining. $r->search({gene_name => "ACT1" }) does not change $r - it returns a new resultset. What you want is

my $r2 = $r->search({gene_name => "ACT1" });
$r2->all;

- john romkey


_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Benjamin Hitz

Re: Resultset chaining

Reply Threaded More More options
Print post
Permalink
Some javascript/style in this post has been disabled (why?)
Genius!  Thanks.   Sorry for the trivial question.

Ben

On Oct 14, 2009, at 2:01 PM, John Romkey wrote:



On Wed, Oct 14, 2009 at 4:53 PM, Benjamin Hitz <[hidden email]> wrote:


On Oct 14, 2009, at 1:46 PM, Rob Kinyon wrote:

On Wed, Oct 14, 2009 at 16:39, Benjamin Hitz <[hidden email]> wrote:

I am having trouble chaining result sets; that is running ->search
subsequently.
So then I tried this:

[snip] Neither will work because you aren't passing hashrefs.


| Oooh... nice catch but the second one succeeds; that is the correct SQL.
|
| And this still fails to add the where clause
|
| perl -I./ -MDB::Mod -e '$r=DB::Mod->schema->resultset("Feature"); $r->search({gene_name=>"ACT1"});$r->all' ;
|
|
| Ben 

That's because you're not chaining. $r->search({gene_name => "ACT1" }) does not change $r - it returns a new resultset. What you want is

my $r2 = $r->search({gene_name => "ACT1" });
$r2->all;

- john romkey

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...

--
Ben Hitz 
Senior Scientific Programmer ** Saccharomyces Genome Database ** GO Consortium
Stanford University ** [hidden email]




_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...
Peter Rabbitson-2

Re: Deployment without cascading updates/deletes

Reply Threaded More More options
Print post
Permalink
In reply to this post by Will Hawes
On Wed, Oct 14, 2009 at 05:38:53PM +0100, Will Hawes wrote:

> While deploying a schema to a SQL Server 2005 database today I ran
> into this database error:
>
> Msg 1785, Level 16, State 0, Line 1236
> Introducing FOREIGN KEY constraint 'tblItemCategory_fk_item_id' on
> table 'tblItemCategory' may cause cycles or multiple cascade paths.
> Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other
> FOREIGN KEY constraints.
> Msg 1750, Level 16, State 0, Line 1236
> Could not create constraint. See previous errors.
>
> OK, so the workaround is to switch off cascading for the constraints
> in question. I had a look at the docs for DBIx::Class::Relationship,
> which state:
>
> "Cascading deletes are off by default on a belongs_to relationship. To
> turn them on, pass cascade_delete => 1 in the $attr hashref."
>
> The default behaviour is not as documented - I had not specified any
> cascade behaviour for the constraint. Setting cascade_delete => 0 or
> cascade_delete => undef had no effect on the generated SQL, which
> still contained "ON DELETE CASCADE ON UPDATE CASCADE".
>
> <snip>
>
> It looks like the user needs to use on_update and on_delete to specify
> exactly what they want the constraint to do, rather than supplying a
> true/false value to cascade_update/cascade_delete (which look as
> though they might be deprecated?). This worked for me - I defined {
> on_delete => 'NO ACTION', on_update => 'NO ACTION' } in the relevant
> belongs_to relation and got the expected SQL.
>
> I'm guessing this is just a case of slightly outdated doc in
> DBIx::Class::Relationship - can someone in the know confirm either way
> please? Happy to patch if required.

Yes, you are entirely correct. A full explanation of what actually
happens can be found here[1]. A patch to other parts of the docs
building on top of this info is very appreciated. Please patch against[2]

Cheers!

[1] http://search.cpan.org/~ribasushi/DBIx-Class-0.08112/lib/DBIx/Class/Relationship/Base.pm#on_delete
[2] http://dev.catalyst.perl.org/repos/bast/DBIx-Class/0.08/trunk/

_______________________________________________
List: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/dbix-class
IRC: irc.perl.org#dbix-class
SVN: http://dev.catalyst.perl.org/repos/bast/DBIx-Class/
Searchable Archive: http://www.grokbase.com/group/dbix-class@...