How to find rows that violate foreign key constraint? - postgresql

My user table is referenced in multiple tables. Is there some way to find which all rows in my user table is referenced in other tables without checking with individual tables that reference user table?
If i try to delete a user, posgres shows me
ERROR: update or delete on table "user" violates foreign key constraint "user _client_fkey" on table "client"
DETAIL: Key (id)=(1) is still referenced from table "user".
Using this feature is there some way can i get all the userids that are referenced in other tables?

Sure just do a 'select * from client where user_id = 1;

Related

Query which will delete other table reference as well as from main table

I have a requirement of deleting records from the Postgres database tables.
We have a Customer table which is the main table, this table contains a primary key which is used in so many other tables as a FOREIGN KEY, I want to delete one of the customers as well as its reference used in other tables. Is there any way to delete the customer from main table as well as from other tables which contains foreign key.
Thanks in Advance.
In the other tables, you want a cascading delete foreign key reference. You can create one in the database using:
alter table othertable add constraint fk_othertable_customerid
foreign key (customerid) references customers(customerid)
on delete cascade;
Note: This assumes that customerid is the name of the column in both tables and that it is already defined in the other tables.
A cascading foreign key constraint does exactly what you specify. When a row is deleted in the reference table, then all related rows are deleted.
If you already have foreign key constraints on customerid, then drop the existing constraint and add the cascading version.

Delete records from a table having foreign key constraint in postgres

I have a table "titles" and a table "scores" in DB. I have witten a query to remove old_movies, shortfilms, games, episodes from my "titles" table. But when i run the query i am getting the below shown error.
ERROR: update or delete on table "titles" violates foreign key
constraint "scores_fk" on table "scores"
DETAIL: Key (id_titles)=(tt3391132) is still referenced from table "scores".
I have tried removing the foreign key constraint on the scores table and then tried removing the records, but it didn't work. Later I tried deleting the record first from "scores" table and then from "titles" table, but still it is showing me the error as above. Please help me solve this as I am new to postgres.
The code to remove records:
DELETE
FROM titles
WHERE content_type = 'game'
OR extract(year from released) < 1950
OR runtime < 10
OR content_type = 'episode'
The code to alter the scores table:
ALTER TABLE scores
DROP CONSTRAINT scores_fk
,ADD CONSTRAINT scores_fk
FOREIGN KEY (id_titles) REFERENCES titles (id_titles) ON DELETE CASCADE;

Postgres inheritance and foreign keys or alternative

I use postgres inheritance in my project.
For example: I have a "user" table and "user_child" that inherits from the "user" table.
I have two records: the first record is created in the user table, the second record is created in the user_child table, while the record from user_child is partially stored in user due to inheritance.
I also have a third table - "homework", it has a column assigned_user - a foreign key to the user table.
When I add an record to the "task" table where the "assigned_user" field refers to a record from the user table, then everything is fine, but when I select a record from the user_child table, I get an error:
ERROR: insert or update on table "homework" violates foreign key
constraint "fk-homework-assigned_user""
DETAIL: Key (assigned_user)=(3) is not present in table "user".
Deleting a constraint helps solve my problem, but I want to use cascading deletion and updating records. Can you tell me what alternatives are there or what I'm doing wrong?
PostgreSQL inheritance doesn't quite work how you expect. Yes, you can see info from the child tables when querying the parent table, but this does not extend to foreign key relationships. The row "belongs" to the child, not the parent. The foreign key reference doesn't touch the child.
It's generally a bad idea to use inheritance in PostgreSQL except for specific cases like making a temporal system or enforcing naming conventions (like interfaces in OOP rather than state inheritance).
PostgreSQL inheritance can be very powerful, but it is generally overused in my opinion. There is already a solution (and cross-database compatible) that more closely follows the traditional relational model.
A better model that would do what you seem to want is the following:
CREATE TABLE "user" (
user_id serial PRIMARY KEY, -- Or UUID or generated column in newer versions
-- other fields that all "children" should share
);
CREATE TABLE user_child (
user_id integer NOT NULL
REFERENCES "user" (user_id) ON UPDATE CASCADE ON DELETE CASCADE,
-- other fields specific to the child
);
CREATE TABLE homework (
homework_id serial PRIMARY KEY,
user_id integer NOT NULL
REFERENCES "user" (user_id) ON UPDATE CASCADE ON DELETE RESTRICT,
-- other fields specific to homework
);
The equivalent to your query for user_child is
SELECT u.user_id
FROM "user" AS u
INNER JOIN user_child AS uc;
And to query user, both parent and child would still be
SELECT u.user_id
FROM "user" AS u;
Adding an inner join is pretty trivial and could be hidden behind a view. Now your foreign key reference to "user" will function correctly.

Can I have a foreign key to a parent table in PostgreSQL?

I'm using inheritance and I ended up having a problem.
If I run:
select count(*) from estate_properties where id = 86820;
I get 1.
But when I try to run this:
insert into property_images (binary_image, name, property_id) values (16779, 'IMG_0096.jpg', 86820)
I get:
********** Error **********
ERROR: insert or update on table "property_images" violates foreign
key constraint "property_images_property_id_fkey" SQL state: 23503
Detail: Key (property_id)=(86820) is not present in table
"estate_properties".
Also ID on estate_properties is SERIAL.
Note: Another table apartments inherits from estate_properties, and 86820 was added to it. Would that make a difference? Also why would it I still have the ID in the parent table and I can select if from there.
Edit:
Looking more closely at the documentation:
http://www.postgresql.org/docs/9.5/static/ddl-inherit.html
I want to achieve this:
5.9.1. Caveats
Specifying that another table's column REFERENCES cities(name) would
allow the other table to contain city names, but not capital names.
There is no good workaround for this case.
EDIT2:
Here is the declaration of the foreign key:
CONSTRAINT property_images_property_id_fkey FOREIGN KEY (property_id)
REFERENCES estate_properties (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
Apparently the answer is here:
Foreign keys + table inheritance in PostgreSQL?
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

Problem adding foreign key in simple setup

I have two tables
Users
Users_Role
I decided to try to add a foreign key as to my understanding it will let me cascade the delete procedure when removing a user from Users (as well as enforce integrity).
So via Management Studio I right clicked my Users_Role table, Design, then went into Relationships. I added a new relationship between the two tables as such:
Foreign Key Base Table: Users_Role
Foreign Key Columns: UserID
Primary/Unique Key Base: Users
Primary/Unique Key columns: ID
When I then try to save, I get the following error:
'Users' table saved successfully
'Users_Role' table
- Unable to create relationship 'FK_Users_Role_Users'.
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK_Users_Role_Users". The conflict occurred in database "db", table "dbo.Users", column 'ID'.
I'm not sure what's going on. Adds the relationship to Users, but not Users_Role? The only thing special about Users_Role is that my primary key consists of two columns, UserID and Role (the only two columns in the table, if that matters). Otherwise, nothing special.
This error means that in your current database, you have entries in the "Users_Role" table which have a "UserID" value that is not present in the Users table as ID.
You first need to find those "rogue" rows and either update or delete them, before you can create the foreign key to enforce referential integrity and avoid such problems in the future.
You can find those by issuing this command:
SELECT * FROM Users_Role
WHERE UserID NOT IN
(SELECT DISTINCT ID FROM Users)