Cannot drop index in postgres because it does not exist - postgresql

In a postgres database, I have a unique constraint and two unique indexes created for the same. I deleted the constraint using the query below:
alter table my_schema.users drop constraint users_dept_uk
It has dropped the constraint and one index but there was a second index which still exists.
The follwoing query is still telling me the index exists:
SELECT r.relname, r.relkind, n.nspname
FROM pg_class r INNER JOIN pg_namespace n ON r.relnamespace = n.oid
WHERE r.relname = 'users_dept_idx';
It gives the following output:
users_dept_idx, i, my_schema
When I execute the query below:
drop index my_schema.users_dept_idx
I am getting the error:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedObject) index "users_dept_idx" does not exist
What am I missing here? Not able to delete it and not able to insert data because of this index which I no longer want.

It is weird that the index name needs quotation around it. Below command worked absolutely fine and dropped the index as well
drop index my_schema."users_dept_idx"

I had a similar problem. It turns out that when you create an index it is created in the same schema as the underlying table. In this case, you don't have to use the "schema" part of the name.
When you drop it you have to use the full name of the index:
create index if not exists ah_login_minute on api.acc_history(login,updated_minute);
drop index if exists ah_login_minute; -- this fails, you have to use full name
drop index if exists api.ah_login_minute; -- this works

Related

Can't drop indexes with schema name

Created index on partition table movies.actors_2010(name) with schemaname movies.actors_2010_name_idx
CREATE INDEX CONCURRENTLY "movies.actors_2010_name_idx" ON movies.actors_2010(name);
Now when I try to drop the index, output shows index doesn't exist and index remain same, can't drop it.
drop index IF EXISTS movies.actors_2010_name_idx;
Any suggestions are helpful.
The problem appears to be that you quoted the identifier "movies.actors_2010_name_idx". That created an index with a . in the name, not an index named "actors_2010_name_idx" in the movies schema. To do that, you should have used
CREATE INDEX CONCURRENTLY "movies"."actors_2010_name_idx" ON "movies"."actors_2010"(name);
or
CREATE INDEX CONCURRENTLY movies.actors_2010_name_idx ON movies.actors_2010(name);
Now to do delete the index with the broken name, you'd use
DROP INDEX IF EXISTS "movies.actors_2010_name_idx";
or possibly
DROP INDEX IF EXISTS "movies"."movies.actors_2010_name_idx";

Drop index postgres, what if duplicate index name exists

below query works perfectly in postgre, because duplicate index within table is not allowed but with in DB it is allowed.
sandbox=# create schema test;
CREATE SCHEMA
sandbox=# create table public.a (a_id integer not null);
CREATE TABLE
sandbox=# create table test.a (a_id integer not null);
CREATE TABLE
sandbox=# create index a_idx on public.a (a_id);
CREATE INDEX
sandbox=# create index a_idx on test.a (a_id);
CREATE INDEX
what happens when I do
DROP INDEX a_idx;
will both the indexes get deleted ?
can I write DROP INDEX test.a.a_idx ?
how the index look up works while deleting ?
What happens depends on the setting of search_path. PostgreSQL searches the existing schemas on search_path in turn, and as soon as it finds an index of that name, it drops the index and is done.
can I write DROP INDEX test.a.a_idx ?
The index is in the same schema as its table, so it would just be DROP INDEX test.a_idx (if you want/need to override search_path)

PostgreSQL multi-column unique constraint causes errors

I am new to postgresql and have a question about multiple column unique constraint.
I got this error when tried to add rows to the table:
ERROR: duplicate key value violates unique constraint "i_rb_on"
DETAIL: Key (a_fk, b_fk)=(296, 16) already exists.
I used this code (short version):
INSERT INTO rb_on (a_fk, b_fk) SELECT a.pk, b.pk FROM A, B WHERE NOT EXISTS (SELECT * FROM rb_on WHERE a_fk=a.pk AND b_fk=b.pk);
i_rb_on is unique constraint / columns (a_fk, b_fk).
It seems that my WHERE NOT EXISTS doesn't provide a protection against the duplicate key error for this kind of unique key.
UPDATE:
INSERT INTO tabA (mark_done, log_time, tabB_fk, tabC_fk)
SELECT FALSE, '2003-09-02 04:05:06', tabB.pk, tabC.pk FROM tabB, tabC, tabD, tabE, tabF
WHERE (tabC.sf_id='SUMMER' AND tabC.sf_status IN(0,1)
AND tabE.inventory_status=0)
AND tabF.tabD_fk=tabD.pk
AND tabD.tabE_fk=tabE.pk
AND tabE.tabB_fk=tabB.pk
AND tabF.tabC_fk=tabC.pk
AND NOT EXISTS (SELECT *
FROM tabA
WHERE tabB_fk=tabB.pk AND tabC_fk=tabC.pk);
In tabA unique index:
CREATE UNIQUE INDEX i_tabA
ON tabA
USING btree
(tabB_fk , tabC_fk );
Only one row (of many) must be inserted into the tabA.
Your WHERE NOT EXISTS never provides proper protection against a unique violation. It only seems to most of the time. The WHERE NOT EXISTS can run concurrently with another insert, so the row is still inserted multiple times and all but one of the inserts causes a unique violation.
For that reason it's often better to just run the insert and let the violation happen if the row already exists.
I can't help you with the exact problem described unless you show the data (as SQL CREATE TABLE and INSERTs) and the real query.
BTW, please don't use old style A, B joins. Use A INNER JOIN B ON (...). It makes it easier to tell which join conditions are supposed to apply to which parts of the query, and harder to forget a join condition. You seem to have done that; you're attempting to insert a cartesian product. I suspect it's just an editing mistake in the query.
I added LIMIT 1 to the end: ...WHERE tabB_fk=tabB.pk AND tabC_fk=tabC.pk) LIMIT1 ;
and it did the trick.
I created a function with LIMIT 1 and ...EXCEPTION WHEN unique_violation THEN ... and it also worked.
But when LIMIT 1 and "NOT EXISTS" are used, I think, it is not necessary to use unique_violation error handling.

How to force drop index relation in postgresql?

In PostgreSQL 9.2 / PostGIS 2.0.2 I had an index on a spatial column, created with
CREATE INDEX tiger_data_sld_the_geom_gist ON tiger_data.sld USING gist(the_geom);
Subsequently dropped the index with
DROP INDEX tiger_data_sld_the_geom_gist;
But now, when I try to recreate, I get this error:
# CREATE INDEX tiger_data_sld_the_geom_gist ON tiger_data.sld USING gist(the_geom);
ERROR: relation "tiger_data_sld_the_geom_gist" already exists
Dropping again doesn't work. It says that the index doesn't exist:
# DROP INDEX tiger_data_sld_the_geom_gist;
ERROR: index "tiger_data_sld_the_geom_gist" does not exist
I haven't found the relation "tiger_data_sld_the_geom_gist" in any list of database objects, have tried DROP TABLE, and searched around for solutions.
What is this mystery relation "tiger_data_sld_the_geom_gist", and how do I remove it so that I can create the index?
Edit:
Also have tried restarting the server, and dumping / dropping / reloading the table (dropped with CASCADE).
Unless you are setting the search_path GUC to (or at least including) the tiger_data schema, you need to add the schema to the index name to issue the DROP INDEX (I'd use it in any case for safety):
DROP INDEX tiger_data.tiger_data_sld_the_geom_gist;
That's because the index always go to the same schema of the table it belongs to. If the above doesn't solve your problem, you can check if this relation name exists and on each schema it is in with the following:
SELECT r.relname, r.relkind, n.nspname
FROM pg_class r INNER JOIN pg_namespace n ON r.relnamespace = n.oid
WHERE r.relname = 'tiger_data_sld_the_geom_gist';
It will return the kind (i for indexes, r for tables, S for sequences and v for views) of any relation that has the name tiger_data_sld_the_geom_gist and name of the schema it belongs to.
Though not particularly efficient, this appears to have done the trick:
Dump the table with pg_dump.
Drop the table.
Dump the database with pg_dump.
Drop the database.
Recreate the database and reload from dump files.

PostgreSQL cannot drop index on partition

I have several partition tables with indexes on them. All indexes can be seen in response of
SELECT indexname FROM pg_catalog.pg_indexes;
But when I'm trying to make DROP INDEX my_index_name; it returns error declaring that there is no index my_index_name.
How can I drop those indexes?
Could be related to your search_path. Try dropping the index prefixed by the schema.
Eg.
SELECT schemaname,tablename,indexname FROM pg_indexes WHERE indexname = 'my_index_name'
Using the results of that query, drop the index:
DROP INDEX some_schema.your_index_name;