Postgres - remove unique contraint (does not exist) - postgresql

I have following table:
I have created unique constraint CREATE UNIQUE INDEX unique_item_media_idx ON mediagalleryitem (article_id, media_id);
Now, I want to remove it and it is impossible for me. When I execute ALTER TABLE "mediagalleryitem" DROP CONSTRAINT unique_item_media_idx; it tells me: constraint "unique_item_media_idx" of relation "mediagalleryitem" does not exist
When I run from CLI \d mediagalleryitem I get:
Indexes:
"mediagalleryitem_pkey" PRIMARY KEY, btree (id)
"unique_item_media_idx" UNIQUE, btree (article_id, media_id)
"idx_1c5848117294869c" btree (article_id)
"idx_1c584811ea9fdd75" btree (media_id)
Foreign-key constraints:
"fk_1c5848117294869c" FOREIGN KEY (article_id) REFERENCES article(id)
"fk_1c584811ea9fdd75" FOREIGN KEY (media_id) REFERENCES media(id)
Whwere is the problem?

What you have there is an index, not a constraint. You can drop it using DROP INDEX unique_item_media_idx. Just as you created an index, you remove an index.

Related

Why does Postgres create multiple indexes on the primary key by default?

From the docs: "PostgreSQL automatically creates a unique index when a unique constraint or primary key is defined for a table."
In my table notifications, I set the id column as the primary key. When I take a look at the indexes on the table using \d notifications the output is:
Indexes:
"notifications_pkey" PRIMARY KEY, btree (id)
"notifications_unique_id" UNIQUE CONSTRAINT, btree (id)
Does this mean I have two indexes on the same column? If so - why does PG do this by default?
Also - does this mean that all my indexes should have this constraint?

Alter the table by adding constraint and using index in postgresql getting an error syntax error at or near "("IDX_emp_PK

CREATE INDEX IDX_emp_PK ON
EMP(ID);
ALTER TABLE EMP ADD
CONSTRAINT PK_emp PRIMARY KEY (ID)
USING INDEX IDX_emp_PK;
There are two errors in your script:
First: you can't use a non-unique index for a primary key constraint, so you need
CREATE UNIQUE INDEX idx_emp_pk ON emp(id);
When you add a primary or unique constraint based on an index, you can't specify columns (as they are already defined in the index):
ALTER TABLE emp ADD
CONSTRAINT pk_emp PRIMARY KEY
USING INDEX idx_emp_pk;

Change Index in Postgres

I have been facing a problem on my django application while trying to add an value to a model. It seems that there is a constraint in the DB that should not be there, according to models.py. The error I get is:
IntegrityError: null value in column "column_x_ptr_id" violates not-null constraint
Doing a \dt in psql, I get:
Indexes:
"mytable_model_pkey" PRIMARY KEY, btree (column_x_ptr_id)
"mytable_model_p_key" UNIQUE CONSTRAINT, btree (column_y_ptr_id)
So, my question is how can I modify this index like so?
"mytable_model_pkey" PRIMARY KEY, btree (column_y_ptr_id)
I'm not sure that would solve the problem though..
Ok this will give you a "more or less" of what you need to do. Your table looks something like this:
CREATE TABLE mytable_model
(
column_x_ptr_id integer NOT NULL,
column_y_ptr_id integer,
CONSTRAINT mytable_model_pkey PRIMARY KEY (column_x_ptr_id),
CONSTRAINT mytable_model_p_key UNIQUE (column_y_ptr_id)
)
You need to drop both indexes, create a new PK on the second column, and remove the NOT NULL constraint:
ALTER TABLE mytable_model DROP CONSTRAINT mytable_model_pkey;
ALTER TABLE mytable_model DROP CONSTRAINT mytable_model_p_key;
ALTER TABLE mytable_model ADD CONSTRAINT mytable_model_pkey PRIMARY KEY (column_y_ptr_id);
ALTER TABLE mytable_model ALTER COLUMN column_x_ptr_id DROP NOT NULL;
Bear in mind that adding a primary key to column_y_ptr_id will change the column to NOT NULL. If any records have NULL in that field, this will fail. Then as I mentioned, you will probably want to put another index on column_x_ptr_id for performance reasons. What type you use is up to you.

How do I copy only 2 tables in Postgres and ignore foreign keys and constraints?

I need to copy 2 tables from production to development. They are the same except the production table has a bit more data in it. I tried pg_dump to dump from production and copy to development, but it complained about foreign key constraints. How do I turn off constraints temporarily? I don't want to copy the whole database because it's too much data, and I want to keep my test data and users.
ALTER TABLE
DROP INDEX
ERROR: cannot drop constraint foods_pkey on table foods because other objects depend on it
DETAIL: constraint fk_rails_7e399284de on table histories depends on index foods_pkey
constraint fk_rails_8d89280489 on table food_nutrients depends on index foods_pkey
Here are the two tables:
Table "public.foods"
Column | Type | Modifiers
------------------+-----------------------------+----------------------------------------------------
id | integer | not null default nextval('foods_id_seq'::regclass)
...
Indexes:
"foods_pkey" PRIMARY KEY, btree (id)
"index_foods_on_food_category_id" btree (food_category_id)
Foreign-key constraints:
"fk_rails_a28abb337f" FOREIGN KEY (food_category_id) REFERENCES food_categories(id)
Referenced by:
TABLE "histories" CONSTRAINT "fk_rails_7e399284de" FOREIGN KEY (food_id) REFERENCES foods(id)
TABLE "food_nutrients" CONSTRAINT "fk_rails_8d89280489" FOREIGN KEY (food_id) REFERENCES foods(id)
And
Table "public.food_categories"
Column | Type | Modifiers
------------+-----------------------------+--------------------------------------------------------------
id | integer | not null default nextval('food_categories_id_seq'::regclass)
...
Indexes:
"food_categories_pkey" PRIMARY KEY, btree (id)
Referenced by:
TABLE "foods" CONSTRAINT "fk_rails_a28abb337f" FOREIGN KEY (food_category_id) REFERENCES food_categories(id)
I also tried --disable-triggers but it didn't help.
You can first copy the "food_categories" table. After that you can copy the "foods" table.

Adding primary key changes column type

Our database currently doesn't define primary keys on any tables. All of the id columns are simply unique indexes. I'm dropping those indexes and replacing them with proper primary keys.
My problem: In Postgres 8.4.7, one table in particular changes the data type from bigint to integer when I add the primary key to the table.
I've got the following table definition:
psql=# \d events
Table "public.events"
Column | Type | Modifiers
-----------------------+--------------------------+-----------------------------------------------------
id | bigint | not null default nextval('events_id_seq'::regclass)
[more columns omitted]
Indexes:
"events_id_unique_pk" UNIQUE, btree (id)
Foreign-key constraints:
"events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
"events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id)
"events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id)
"events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE
"events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id)
"events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id)
"events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id)
Referenced by:
TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE
Triggers:
event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate()
This is what happens:
psql=# ALTER TABLE events ADD PRIMARY KEY (id);
NOTICE: ALTER TABLE / ADD PRIMARY KEY will create implicit index "events_pkey" for table "events"
ALTER TABLE
psql=# \d events
Table "public.events"
Column | Type | Modifiers
-----------------------+--------------------------+-----------------------------------------------------
id | integer | not null default nextval('events_id_seq'::regclass)
[more columns omitted]
Indexes:
"events_pkey" PRIMARY KEY, btree (id)
"events_id_unique_pk" UNIQUE, btree (id)
Foreign-key constraints:
"events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
"events_event_configs_id_fk" FOREIGN KEY (event_config_id) REFERENCES event_configs(id)
"events_pdu_circuitbreaker_id_fk" FOREIGN KEY (pdu_circuitbreaker_id) REFERENCES pdu_circuitbreaker(id)
"events_pdu_id_fk" FOREIGN KEY (pdu_id) REFERENCES pdus(id) ON DELETE CASCADE
"events_pdu_outlet_id_fk" FOREIGN KEY (pdu_outlet_id) REFERENCES pdu_outlet(id)
"events_sensor_id_fk" FOREIGN KEY (sensor_id) REFERENCES sensors(id)
"events_user_id_fk" FOREIGN KEY (clearing_user_id) REFERENCES users(id)
Referenced by:
TABLE "events" CONSTRAINT "events_clearing_event_ref_fk" FOREIGN KEY (clearing_event_id) REFERENCES events(id)
TABLE "event_params" CONSTRAINT "events_params_event_id_fk" FOREIGN KEY (event_id) REFERENCES events(id) ON DELETE CASCADE
Triggers:
event_validate BEFORE INSERT OR UPDATE ON events FOR EACH ROW EXECUTE PROCEDURE event_validate()
I considered a few workarounds, but I'd really rather know why it's happening. There are a few other tables that also use bigint, so I don't want to just hack a solution in place.
This is scripted with Liquibase, but it happens directly in the Postgres console too.
Update
Two other points:
I can create a simple table with a bigint id and a unique index on id, add the primary key, and the column type stays the same.
All tables are empty at the time execution.
Could it have something to do with the constraints?
That's pretty interesting. I can't reproduce it with version 9.1.0 (yes, I should upgrade too!). But then I don't know precisely how the original table and sequence were created.
This page seems to allude to a similar automatic change of types between SERIAL and INTEGER: http://grover.open2space.com/content/migrate-data-postgresql-and-maintain-existing-primary-key
Could it be something like creating the table using SERIAL instead of BIGSERIAL, and then forcing the type to BIGINT? Something in between the sequence and primary key manipulations might have reset it.
I wasn't able to reproduce this the next day, even after reproducing it multiple times with witnesses the first time it occurred. I'm chalking it up to gremlins.