Cannot drop index because unique constraint requires it (postgres) - postgresql

Running Postgres 9.6.
I'm trying to write database migration code to drop a redundant unique constraint and index. The problem is that in some installations these index and constraint exist, and in others they don't.
The recommended way to drop would be:
alter table <table_name> drop constraint <unique_name>
But that fails when the constraint does not exist, and there is no "if exists" clause for this. There is an "if exists" clause to the "drop index" command, but that initially fails as well:
db=> drop index if exists <unique_name>;
ERROR: cannot drop index <unique_name> because constraint <unique_name> on table <table_name> requires it
But wait, "drop index" has a "cascade" option to remove dependent objects, so we can use that!
Well, no. I get the same response:
db=> drop index if exists <unique_name> cascade;
ERROR: cannot drop index <unique_name> because constraint <unique_name> on table <table_name> requires it
Note: I've seen a lot of seemingly-related answers where "cascade" solved the problem for people, but these all mention foreign-key constraints, not unique constraints.
Note: This does not relate to the fact that cascade is not supported when trying to remove the index concurrently; when you add the "concurrently" keyword, you get a very explicit
ERROR: DROP INDEX CONCURRENTLY does not support CASCADE
Is this a known bug? Or am I missing something?

You can use a DO statement and trap the error:
DO
$$BEGIN
ALTER TABLE <table_name> DROP CONSTRAINT <unique_name>;
EXCEPTION
WHEN undefined_object
THEN NULL; -- ignore the error
END$$;

Related

Postgres ALTER TABLE ADD CONSTRAINT IF NOT EXISTS not working

I need to add a Constraint if not exists and am hitting the following error. Note that a similar if not exists for a new Column, right above it, does work. There's some syntax error when adding a Constraint, am I missing something?
alter table requests_t
add constraint if not exists
valid_bias_check CHECK (bias_flag::text = ANY (ARRAY['Y'::character varying::text, 'N'::character varying::text]));
Error
ERROR: syntax error at or near "not"
LINE 2: add constraint if not exists
Since Postgres doesn't support this syntax with constraints (see a_horse_with_no_name's comment), I rewrote it as:
alter table requests_t
drop constraint if exists valid_bias_check;
alter table requests_t
add constraint
valid_bias_check CHECK (bias_flag::text = ANY (ARRAY['Y'::character varying::text, 'N'::character varying::text]));

Postgres constraint invalid after dropping and recreating

We are using postgres Aurora RDS ( version 12.4)
We have a table on which we had a unique constraint on three columns (Column_a , column_b, column_c). After some time ,we realized we would need to add one more column to the unique constraint while the table already had some data.
So we decided to drop the constraint and recreate it with the new set of columns. The following are the statements used:
alter table table_name drop constraint constraint_name ;
ALTER TABLE ONLY table_name
ADD unique constraint constraint_name ( column_new ,column_a, column_b , column_c) ;
After recreating the constraint the constraint is shown as invalid and on conflict statements using this constraint are failing with an error message:
"there is no unique or exclusion constraint matching the ON CONFLICT specification"
We tried creating a duplicate table . We could not replicate the problem when this backup table had no data . But on filling in some data into the table and trying the same steps we could replicate the problem . The new constraint was showing as invalid .
We would like to understand what causes the constraint to be invalid. Is there any restriction on dropping constraints on tables already having data? We would like to know if we could overcome this without truncating the table.

Cannot drop constraint with postgres even using adminer or sql command CONSTRAINT DOESN'T EXIST

I cannot drop a constraint in postgres even using adminer
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
Error in query : ERROR: constraint "constraint_name" of relation "table_name" does not exist
but if I create a new one like :
ALTER TABLE table_name
ADD CONSTRAINT my_new_constraint(column1, column2, ... column_n);
Then it works and I can drop it.
The one who made the constraint I try to drop did it this way two years ago:
create unique index constraint_name on table_name (column1,lower(column2),coalesce(deleted_at,\'19000101\')
If anyone has got any idea to drop this constraint?
CREATE UNIQUE INDEX creates an index that needs to be dropped with DROP INDEX, not a table constraint.

How can use the cascade in Postgresql query while deleting record from parent table

How can we use the cascade in PostgreSQL while deleting the one record from the parent table that is being referred in other child tables. Currently it is giving the syntax error.
ERROR: syntax error at or near "cascade"
LINE 1: DELETE FROM fs_item where itemid = 700001803 cascade;
You have to add ON DELETE CASCADE constraint in following way:
ALTER TABLE table1 ADD CONSTRAINT "tbl1_tbl2_fkey" FOREIGN KEY(reference_key) REFERENCES table2 ON DELETE CASCADE;
Then, you can simply execute the DELETE query
DELETE FROM fs_item where itemid = 700001803
There is no CASCADE for delete statements. You set the foreign key to CASCADE deletes and then it happens for you automatically.

update pg_constraint has no effect (postgres)

I tried to change all foreign keys in PostgreSQL at once to cascade on delete:
UPDATE pg_catalog.pg_constraint
SET confupdtype='c', confdeltype='c', confmatchtype='u'
WHERE connamespace=2200;
There are no errors, and when I inspect the tables with pgadmin, it looks right, but when I try to delete a referenced table-line it comes to a constraint error. Just the SQL statement works:
ALTER TABLE tblname
DROP CONSTRAINT IF EXISTS fk3e2e4a8ff123848a;
ALTER TABLE tblname
ADD CONSTRAINT fk3e2e4a8ff123848a FOREIGN KEY (field)
REFERENCES othertable (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE;
Any idea why changing pg_catalog.pg_constraint is not working? even restarting the service after didn't help.
Really you shouldn't be updating pg_* tables.
Use a command like
ALTER TABLE YOURTABLE DISABLE TRIGGER;
Check this link out.
http://archives.postgresql.org/pgsql-general/2011-10/msg00802.php