Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreign keys + table inheritance in PostgreSQL?

I have three tables: organization, organization_teams and org_users. Here organization_teams is inherited from organization. So suppose if a record is added in organizations_teams it will get the organization table id as value for id column in organization_teams.

org_users has foreign key on id column of organization. Now when I try to insert data in org_users it giving me error as below

insert or update on table "org_users" violates foreign key constraint "org_users_organizations"
DETAIL:  Key (org_id)=(12) is not present in table "organizations"

Why?

like image 228
Supriya Pansare Avatar asked Jun 23 '14 07:06

Supriya Pansare


People also ask

Are foreign keys inheritance?

No. Sequences are not inherited. This is known caveat: A serious limitation of the inheritance feature is that indexes (including unique constraints) and foreign key constraints only apply to single tables, not to their inheritance children postgresql.org/docs/current/static/…

What is table inheritance in PostgreSQL?

Inheritance in PostgreSQL allows you to create a child table based on another table, and the child table will include all of the columns in the parent table.

Does Postgres support inheritance?

PostgreSQL supports an advanced object-relational mechanism known as inheritance . Inheritance allows a table to inherit some of its column attributes from one or more other tables, creating a parent-child relationship.


3 Answers

It's covered in the user manual.

The short version: you can use foreign keys, or table inheritance, but not both. This isn't inherently impossible, it's just that it's technically quite difficult to implement unique indexes that span inherited tables in PostgreSQL in a fast, reliable manner. Without that, you can't have a useful foreign key. Nobody's successfully implemented it well enough for a patch adding support to be accepted into PostgreSQL yet.

A foreign key can point to a table that is part of an inheritance hierarchy, but it'll only find rows in that table exactly. Not in any parent or child tables. To see which rows the foreign key sees, do a SELECT * FROM ONLY thetable. The ONLY keyword means "ignoring inheritance" and that's what the foreign key lookup will do.

like image 133
Craig Ringer Avatar answered Sep 29 '22 01:09

Craig Ringer


The only workaround i have found is:

  1. create function returning trigger for checking existence of some id in inherited table
  2. create a constraint trigger instead of FK
like image 34
shcherbak Avatar answered Sep 28 '22 23:09

shcherbak


Completely agree with @Craig Ringer, we can't use foreign keys along with inheritance.

But if we are sure that we are going to insert correct data, and we want to use foreign key in org_users, we can do one thing.

We can create a child table of org_users say org_users_child (with no foreign key) as below

CREATE TABLE org_users_child () INHERITS (org_users);

Now we can insert data in this child table.

Now if we query over org_users table, we can find desired results.

like image 38
Anil Agrawal Avatar answered Sep 28 '22 23:09

Anil Agrawal