Thread: How to temporarily disable a table's FK constraints?

How to temporarily disable a table's FK constraints?

From
"Kynn Jones"
Date:
Hi, everyone.

Is there a standard way to disable a table foreign-key constraint temporarily?

I thought that this would be a fairly common thing to want to do, but
I only found this snippet online:

-- to disable
UPDATE pg_class SET reltriggers=0 WHERE relname = 'your_table';

-- to re-enable
UPDATE pg_class SET reltriggers = count( * )
  FROM pg_trigger WHERE pg_class.oid=tgrelid AND relname = 'your_table';

and it appears that one needs to be root to execute these statements.

Is there any other way for non-root users?

TIA!

kj

Re: How to temporarily disable a table's FK constraints?

From
Erik Jones
Date:
On Nov 5, 2007, at 10:50 AM, Kynn Jones wrote:

> Hi, everyone.
>
> Is there a standard way to disable a table foreign-key constraint
> temporarily?
>
> I thought that this would be a fairly common thing to want to do, but
> I only found this snippet online:
>
> -- to disable
> UPDATE pg_class SET reltriggers=0 WHERE relname = 'your_table';
>
> -- to re-enable
> UPDATE pg_class SET reltriggers = count( * )
>   FROM pg_trigger WHERE pg_class.oid=tgrelid AND relname =
> 'your_table';
>
> and it appears that one needs to be root to execute these statements.
>
> Is there any other way for non-root users?

Can you explain what it is you're actually trying to do?  As in,
what's your use case for needing to do this?  While there isn't any
specific 'disable foreign key' functionality, there are different
solutions to what use cases where people think they need this.  The
one you listed is actually a total hack and should really be avoided
unless your really know what you're doing as what you're doing is
forcing an inconsistency in the catalogs and if you forget to restore
them with that second query, well, good luck to the next guy trying
to figure out what you did.  You'd be better off just dropping the
foreign key than going that route.

I think a good addition to the pieces of advice that get tacked on to
the end of the list messages would be something along the lines of:
"Don't edit the catalogs unless you absolutely, positively know what
you're doing and even then, think again."

Erik Jones

Software Developer | Emma®
erik@myemma.com
800.595.4401 or 615.292.5888
615.292.0777 (fax)

Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com



Re: How to temporarily disable a table's FK constraints?

From
Ron Johnson
Date:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/05/07 10:50, Kynn Jones wrote:
> Hi, everyone.
>
> Is there a standard way to disable a table foreign-key constraint temporarily?
>
> I thought that this would be a fairly common thing to want to do, but
> I only found this snippet online:
>
> -- to disable
> UPDATE pg_class SET reltriggers=0 WHERE relname = 'your_table';
>
> -- to re-enable
> UPDATE pg_class SET reltriggers = count( * )
>   FROM pg_trigger WHERE pg_class.oid=tgrelid AND relname = 'your_table';
>
> and it appears that one needs to be root to execute these statements.
>
> Is there any other way for non-root users?

The whole idea of enforcing Relational Integrity in the database
engine is to *not* allow "regular users" to bypass data integrity
checks.

- --
Ron Johnson, Jr.
Jefferson LA  USA

Give a man a fish, and he eats for a day.
Hit him with a fish, and he goes away for good!

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)

iD4DBQFHL1PLS9HxQb37XmcRAm7zAKDbdYSymz3zIyKmfdU5wPjtpVTAlwCYoEA/
DI1Z2Fbgo62k6C2P8gsCQQ==
=Np96
-----END PGP SIGNATURE-----

Re: How to temporarily disable a table's FK constraints?

From
"Kynn Jones"
Date:
On 11/5/07, Erik Jones <erik@myemma.com> wrote:

> On Nov 5, 2007, at 10:50 AM, Kynn Jones wrote:
> > Is there a standard way to disable a table foreign-key constraint
> > temporarily?
> >
> > I thought that this would be a fairly common thing to want to do...

> Can you explain what it is you're actually trying to do?  As in,
> what's your use case for needing to do this?

A Perl script that needs to update a referring table with many new
entries before knowing the foreign keys for each new record.  (I
described a similar situation in a recent post, Subject: Populating
large DB from Perl script.)

Also, Ron, the *owner* of a table is not a "regular user" as far as
that table is concern.  That user has special privileges, including
that of dropping constraints.  What I seek to do is no greater a
violation of the idea of enforcing relational integrity than is the
ability to drop constraints altogether.

BTW, I realize that I can just drop and reinstate constraints, but
from the point of view of writing a Perl script to do all this, it
would be much easier if I could just disable temporarily all the FK
constraints on a table.

kj

Re: How to temporarily disable a table's FK constraints?

From
"Scott Marlowe"
Date:
On 11/5/07, Kynn Jones <kynnjo@gmail.com> wrote:
> On 11/5/07, Erik Jones <erik@myemma.com> wrote:
>
> > On Nov 5, 2007, at 10:50 AM, Kynn Jones wrote:
> > > Is there a standard way to disable a table foreign-key constraint
> > > temporarily?
> > >
> > > I thought that this would be a fairly common thing to want to do...
>
> > Can you explain what it is you're actually trying to do?  As in,
> > what's your use case for needing to do this?
>
> A Perl script that needs to update a referring table with many new
> entries before knowing the foreign keys for each new record.  (I
> described a similar situation in a recent post, Subject: Populating
> large DB from Perl script.)
>
> Also, Ron, the *owner* of a table is not a "regular user" as far as
> that table is concern.  That user has special privileges, including
> that of dropping constraints.  What I seek to do is no greater a
> violation of the idea of enforcing relational integrity than is the
> ability to drop constraints altogether.
>
> BTW, I realize that I can just drop and reinstate constraints, but
> from the point of view of writing a Perl script to do all this, it
> would be much easier if I could just disable temporarily all the FK
> constraints on a table.

But those aren't the same things.  If userA has permission to add /
drop FKs, and drops them, inserts data, and then reapplies the foreign
key, userA will get an error if they've managed to dork out the data
(i.e. data with no foreign key).

OTOH, if userA just switches off FK enforcement, adds data and turns
them back on, the data can now be incoherent.

Things get even more interesting if other users are involved.

If one and only one user ever uses the table, and that use is
absolutely sure the data is coherent, then they are the same thing.
Otherwise, they certainly are not.

Re: How to temporarily disable a table's FK constraints?

From
Erik Jones
Date:
On Nov 5, 2007, at 11:52 AM, Kynn Jones wrote:

> On 11/5/07, Erik Jones <erik@myemma.com> wrote:
>
>> On Nov 5, 2007, at 10:50 AM, Kynn Jones wrote:
>>> Is there a standard way to disable a table foreign-key constraint
>>> temporarily?
>>>
>>> I thought that this would be a fairly common thing to want to do...
>
>> Can you explain what it is you're actually trying to do?  As in,
>> what's your use case for needing to do this?
>
> A Perl script that needs to update a referring table with many new
> entries before knowing the foreign keys for each new record.  (I
> described a similar situation in a recent post, Subject: Populating
> large DB from Perl script.)

So, let me rephrase to see if I get you correctly:  you want to
insert a lot of data and then go back and update the inserted rows
with the foreign key values?  If that's the case and you can do all
of that in one transaction then you should talk to your dba or
whomever the table owner is to see about redefining the foreign key
as being deferrable.  That will make it so that the foreign key
constraints aren't checked until transaction commit time rather than
at statement execution time.

Erik Jones

Software Developer | Emma®
erik@myemma.com
800.595.4401 or 615.292.5888
615.292.0777 (fax)

Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com



Re: How to temporarily disable a table's FK constraints?

From
Sam Mason
Date:
On Mon, Nov 05, 2007 at 01:52:54PM -0400, Kynn Jones wrote:
> BTW, I realize that I can just drop and reinstate constraints, but
> from the point of view of writing a Perl script to do all this, it
> would be much easier if I could just disable temporarily all the FK
> constraints on a table.

Do you really want to disable the foreign key constraint, or just defer
their checking till you commit the transaction?  If you just want to
defer checking, then [1] may help.


  Sam

 [1] http://www.postgresql.org/docs/current/static/sql-set-constraints.html

Re: How to temporarily disable a table's FK constraints?

From
"Kynn Jones"
Date:
On 11/5/07, Erik Jones <erik@myemma.com> wrote:

> ...see about redefining the foreign key
> as being deferrable...

Yep, that'll do it.  Thanks!

kj

Re: How to temporarily disable a table's FK constraints?

From
andy
Date:
Kynn Jones wrote:
> Hi, everyone.
>
> Is there a standard way to disable a table foreign-key constraint temporarily?
>
> I thought that this would be a fairly common thing to want to do, but
> I only found this snippet online:
>
> -- to disable
> UPDATE pg_class SET reltriggers=0 WHERE relname = 'your_table';
>
> -- to re-enable
> UPDATE pg_class SET reltriggers = count( * )
>   FROM pg_trigger WHERE pg_class.oid=tgrelid AND relname = 'your_table';
>
> and it appears that one needs to be root to execute these statements.
>
> Is there any other way for non-root users?
>
> TIA!
>
> kj

Hey, I was just thinking about this... instead of disabling the FK's,
what about adding a temp table where you could COPY into, then fire off
a bunch of update's to setup the id fields, etc, etc, then do an Insert
into realtable select * from temptable?

-Andy

Re: How to temporarily disable a table's FK constraints?

From
"Kynn Jones"
Date:
On 11/5/07, andy <andy@squeakycode.net> wrote:
> Hey, I was just thinking about this... instead of disabling the FK's,
> what about adding a temp table where you could COPY into, then fire off
> a bunch of update's to setup the id fields, etc, etc, then do an Insert
> into realtable select * from temptable?

I like this idea.  It's very straightforward.  Thanks!

kj