Postgres: drop foreign key constraint query getting stuck - postgresql

I wanted to remove all foreign key constraints from a schema. I was successful in dropping constraints from most of the tables but in few of them drop foreign key constraint query is getting stuck.
ALTER TABLE table_name DROP CONSTRAINT fkey_name;
I tried truncate cascade but it was also getting stuck. I deleted all rows from both the tables manually. Still getting stuck.
Edits: By getting stuck I mean query continues running for long time without any error message even though tables are empty.

Check for any dead locks using
SELECT * FROM pg_stat_activity;
If any then kill and run below sql,and then drop using
SELECT pg_terminate_backend(pid);
If Not solved check for any virtual transaction
SELECT database, gid FROM pg_prepared_xacts;
Rollback using
ROLLBACK PREPARED 'gid';

Related

insert into, on conflict do update, why fail? postgresql, pgadmin

I am trying to insert a new table into a big old table to update multiple rows ,
here is my query:
INSERT INTO site_settings (set_id, set_sit_id,set_setting_name,set_setting_type)
SELECT set_id, set_sit_id, replace(TempTable2.stp_device_pool_filter, '${siteShortName}', TempTable2.sit_short_name), set_setting_type from TempTable2 where set_setting_type='DEVICE_POOL'
ON CONFLICT (set_id) DO UPDATE
SET set_sit_id=excluded.set_sit_id,
set_setting_name=excluded.set_setting_name,
set_setting_type=excluded.set_setting_type;
it returns me the message:
duplicate key value violates unique constraint "unique_site_setting"
DETAIL: Key (set_sit_id, set_setting_name, set_setting_type)=(13, SBA123-rr, DEVICE_POOL) already exists.
However, I used to use the similar query to update a much more complicated table, it worked.
don't know what's the problem

How to Check if a Foreign Key Exists on a Specific Table in PostgreSQL

I have a foreign key named user__fk__store_id that was supposed to be created on the user table.
However, I made a mistake and instead have it created on another table I have named client.
My servers have an automated process that reads from a JSON file I created with what new tables to create, remove, etc... Every time a server needs to be upgraded with new stuff, it will run through this JSON file and run the queries it needs to.
In this case, in the json file, I'm trying to have it drop the existing incorrect foreign key constraint that was created on the client table, and recreate it correctly on the user table. So technically, it should be running these 2 queries back to back:
ALTER TABLE client DROP CONSTRAINT user__fk__store_id;
ALTER TABLE user ADD CONSTRAINT user__fk__store_id;
The problem I'm having is I can't figure out the query to run in order to see if the user__fk__store_id exists on the client table. I only know how to check if the constraint exists on any table in the database with the following:
SELECT COUNT(1) FROM pg_constraint WHERE conname='user__fk__store_id';
This would be a problem because this means every time I run my upgrade script on my servers, it will always think the constraint of that name already exists, but when it attempts to run the drop query it will error out because it can't find that constraint in the client table.
Is there a query I can run to check not just if the constraint exists, but also if it exists in a specific table?
I found the answer to my own question, I can just run the following query:
SELECT COUNT(1) FROM information_schema.table_constraints WHERE constraint_name='user__fk__store_id' AND table_name='client';
Above answer works fine, but following returns true/false and also checks for schema
SELECT EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE table_schema='schema_name' AND table_name='MyTable' AND
constraint_name='myTable_fkName_fkey');

Postgres: Error constraint "fk" of relation "tbl" does not exist (with Yii - PHP)

I searched for this problem. But my postgres user has enough grant and I do not think I have misspelling error. However I am newbie.
I have this error message:
21:38:03 set search_path='public'
21:38:03 ALTER TABLE public.tbl_user DROP CONSTRAINT "fk-user-access-user-id"
21:38:03 ERROR: constraint "fk-user-access-user-id" of relation "tbl_user" does not exist
I use the PhpStorm. I just open the database view, expanded the tbl_user table, right click and select "drop". And I got this error in the console.
So the above SQL command generated by the PhpStorm.
Then I tried with these commands manually on Ubuntu:
ALTER TABLE tbl_user DROP CONSTRAINT "fk-user-access-user-id"
ALTER TABLE "tbl_user" DROP CONSTRAINT "fk-user-access-user-id"
But I get the same error.
In the PhpStorm I see this definition:
"fk-user-access-user-id" FOREIGN KEY (access_id) REFERENCES tbl_access (id)
The tbl_access table exists with the primary id key.
I do not understand this error message, because the "fk-user-access-user-id" foreign key is at the tbl_user and so for me the 'relation "tbl_user" does not exist' strange. I do not understand.
I tried to find similar problem on StackOverflow, but I gave up after 20x question reading.
By the way, the postgres code was generated by the Yii framework.
$this->addColumn('{{%user}}', 'access_id', $this->integer()->notNull()->defaultValue(1)->after('status'));
$this->addForeignKey('fk-user-access-user-id', '{{%user}}', 'access_id', '{{%access}}', 'id');
first row mean add access_id column to the user table.
second row: create foreign key with 'fk-user...' name on tbl_user table's access_id column references to tbl_access table's id column.
So I used this PHP code to generate this SQL commands. I prefer this way because for me the migration files are very useful.
Most likely the definition and actual implementation in your underlying DB has changed from what the app has recorded. Depending on what the history is, either a change in the app for that foreign key relationship was not migrated to persist the change at the database level, or someone has executed some operation directly at the DB level to remove the relationship. You will need to sync up the app layer to the DB at this point I would think.

How to work around error "Delete Prevented by referential constraint" in DB2?

So the problem I have is in my task provided to us by the Professor we are to
create tables
insert records to each table.
update and delete (minimum of 1 record) from each table
using a DB2 Script that is following the old standard where COLLECTIONS are created instead of SCHEMAS
steps 1 and 2 are done. the updates are done. my deletes are giving me a hard time. an example would be this.
CREATE TABLE UMALIK8.CAMPUS (
CAMPUS_ID VARCHAR (10) NOT NULL,
CAMPUS_NAME VARCHAR (30) NOT NULL,
MANAGER_NUM VARCHAR (10) NOT NULL,
CONSTRAINT UMALIK8.CAMPUS_PK PRIMARY KEY (CAMPUS_ID),
CONSTRAINT UMALIK8.CAMPUS_FK FOREIGN KEY (MANAGER_NUM)
REFERENCES UMALIK8.MANAGER(MANAGER_NUM)
ON DELETE CASCADE);
INSERT INTO UMALIK8.CAMPUS (CAMPUS_ID, CAMPUS_NAME, MANAGER_NUM)
VALUES ('King', 'King Campus', 'M021386');
DELETE FROM UMALIK8.CAMPUS
WHERE CAMPUS_ID = 'King';
so when I try to delete it, it says delete prevented by referential constraint "roomassign_fk" which doesn't make sense to me because the roomassign table is like 3 or 4 tables AFTER the campus table, the campus is the parent table, and the manager number is from the manager table and the parent table for manager table is Employee table....all throughout the delete script im getting referential errors and I don't know why. Even in my adult table but my adult table has no foreign keys, its only got a primary key on its own, and its got a bunch of child tables....
Now the order of my script is
Tables,
Inserts,
Updates,
Deletes
all separated from each other in one long script
any idea how to fix this? what am i doing wrong?
your help is greatly appreciated, thanks!
As discussed on the comments with the OP turns out that the issue is about a trigger on the table CAMPUS. As the OP asked I'm putting this as an answer.
Is it possible to exist on this table UMALIK8.CAMPUS a trigger which is inserting registries in a table that has an FK to it?
What I mean with a trigger is that if your table has an after insert trigger that would mean something like this: you run the insert command on CAMPUS, after the insert happens the DB2 will call the trigger and insert in a ROOM (i think that is the name of other table given the FK name) one registry which will be linked (by FK) to the one you just inserted on CAMPUS, then if you try to delete the registry on CAMPUS the referential constraint "roomassign_fk" will happen because you have a child registry that is linked to the one in CAMPUS

PostgreSQL - disabling constraints

I have a table with approx 5 million rows which has a fk constraint referencing the primary key of another table (also approx 5 million rows).
I need to delete about 75000 rows from both tables. I know that if I try doing this with the fk constraint enabled it's going to take an unacceptable amount of time.
Coming from an Oracle background my first thought was to disable the constraint, do the delete & then reenable the constraint. PostGres appears to let me disable constraint triggers if I am a super user (I'm not, but I am logging in as the user that owns/created the objects) but that doesn't seem to be quite what I want.
The other option is to drop the constraint and then reinstate it. I'm worried that rebuilding the constraint is going to take ages given the size of my tables.
Any thoughts?
edit: after Billy's encouragement I've tried doing the delete without changing any constraints and it takes in excess of 10 minutes. However, I have discovered that the table from which I'm trying to delete has a self referential foreign key ... duplicated (& non indexed).
Final update - I dropped the self referential foreign key, did my delete and added it back in. Billy's right all round but unfortunately I can't accept his comment as the answer!
Per previous comments, it should be a problem. That said, there is a command that may be what you're looking to - it'll set the constraints to deferred so they're checked on COMMIT, not on every delete. If you're doing just one big DELETE of all the rows, it won't make a difference, but if you're doing it in pieces, it will.
SET CONSTRAINTS ALL DEFERRED
is what you are looking for in that case. Note that constraints must be marked as DEFERRABLE before they can be deferred. For example:
ALTER TABLE table_name
ADD CONSTRAINT constraint_uk UNIQUE(column_1, column_2)
DEFERRABLE INITIALLY IMMEDIATE;
The constraint can then be deferred in a transaction or function as follows:
CREATE OR REPLACE FUNCTION f() RETURNS void AS
$BODY$
BEGIN
SET CONSTRAINTS ALL DEFERRED;
-- Code that temporarily violates the constraint...
-- UPDATE table_name ...
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
What worked for me was to disable one by one the TRIGGERS of those tables that are gonna be involved in the DELETE operation.
ALTER TABLE reference DISABLE TRIGGER ALL;
DELETE FROM reference WHERE refered_id > 1;
ALTER TABLE reference ENABLE TRIGGER ALL;
Solution is working in version 9.3.16. In my case time went from 45 minutes to 14 seconds executing DELETE operations.
As stated in the comments section by #amphetamachine, you will need to have admin privileges to the tables to perform this task.
If you try DISABLE TRIGGER ALL and get an error like permission denied: "RI_ConstraintTrigger_a_16428" is a system trigger (I got this on Amazon RDS), try this:
set session_replication_role to replica;
If this succeeds, all triggers that underlie table constraints will be disabled. Now it's up to you to make sure your changes leave the DB in a consistent state!
Then when you are done, reenable triggers & constraints for your session with:
set session_replication_role to default;
(This answer assumes your intent is to delete all of the rows of these tables, not just a selection.)
I also had to do this, but as part of a test suite. I found the answer, suggested elsewhere on SO. Use TRUNCATE TABLE as follows:
TRUNCATE TABLE <list-of-table-names> [RESTART IDENTITY] [CASCADE];
The following quickly deletes all rows from tables table1, table2, and table3, provided that there are no references to rows of these tables from tables not listed:
TRUNCATE TABLE table1, table2, table3;
As long as references are between the tables listed, PostgreSQL will delete all the rows without concern for referential integrity. If a table other than those listed references a row of one of these tables, the query will fail.
However, you can qualify the query so that it also truncates all tables with references to the listed tables (although I have not tried this):
TRUNCATE TABLE table1, table2, table3 CASCADE;
By default, the sequences of these tables do not restart numbering. New rows will continue with the next number of the sequence. To restart sequence numbering:
TRUNCATE TABLE table1, table2, table3 RESTART IDENTITY;
My PostgreSQL is 9.6.8.
set session_replication_role to replica;
work for me but I need permission.
I login psql with super user.
sudo -u postgres psql
Then connect to my database
\c myDB
And run:
set session_replication_role to replica;
Now I can delete from table with constraint.
Disable all table constraints
ALTER TABLE TableName NOCHECK CONSTRAINT ConstraintName
-- Enable all table constraints
ALTER TABLE TableName CHECK CONSTRAINT ConstraintName