How to change a table constraint to deferrable in postgresql? - postgresql

I have this simple contraint set on my sales table
CONSTRAINT sales_stamping_id_key UNIQUE (company_id, stamping_id, invoice_number, billed)
and i can't seem to find a way to change this constraint to deferrable without deleting the constraint. Is there a way to do this???

You can alter the unique constraint like so:
alter table foo add constraint bar_idx unique using index bar_idx deferrable;
http://www.postgresql.org/docs/current/static/sql-altertable.html

Related

Alter a unique index to set it deferrable in postgresq

I need to alter a unique index which has already been created to set it deferrable. In postgres 9.6. Basically, i do something like:
DROP TABLE IF EXISTS test;
CREATE TABLE test (id integer);
ALTER TABLE test ADD CONSTRAINT unique_id unique(id);
ALTER TABLE test ALTER CONSTRAINT unique_id DEFERRABLE INITIALLY DEFERRED;
But i get
ERROR: constraint "unique_id" of relation "test" is not a foreign key constraint
Documentation does not seem to mention that such action cannot be performed. What am i missing?
Per the documentation:
ALTER CONSTRAINT
This form alters the attributes of a constraint that was previously created. Currently only foreign key constraints may be altered.
Instead you can:
ALTER TABLE test DROP CONSTRAINT unique_id;
ALTER TABLE test ADD CONSTRAINT unique_id unique(id) DEFERRABLE INITIALLY DEFERRED;

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.

Postgres Drop constraints order

When dropping constraints from a postgres table , How to know the safest order to drop the constraints. Like ,
1) The foreign key constraints can be dropped first [as they have to be droppped before primary key constraint]
Then the order of removing the constraints can be in any order . like check constraint, unique constraint, not nulls, default , primary key constraints . Am I correct
No constraint on a PostgreSQL table depends on another constraint on the same table, so the order does not matter here.
The only dependency between constraints is the dependency of a foreign key on the primary or unique key on the target table.
So you can either remove all foreign key constraints first and then all other constraints, or you can use ALTER TABLE ... DROP CONSTRAINT ... CASCADE which will automatically drop all dependent constraints, then you don't have to care about the order at all.

How to disable foreign key and primary key constraint temporarily in PostgreSQL?

I have one table that has two fields. The structure is like this:
CREATE TABLE raw_links
(
value_id bigint NOT NULL,
raw_id integer NOT NULL,
CONSTRAINT raw_links_pk PRIMARY KEY (raw_id, dp_id),
CONSTRAINT raw_fk FOREIGN KEY (raw_id)
REFERENCES raw_data (raw_data_id) MATCH SIMPLE
ON UPDATE RESTRICT ON DELETE RESTRICT
)
I have to delete 5 million records from this table. For that I want to disable both constraints so that deletion will be faster. After deletion I want to create both constraints.
You can do ALTER TABLE DROP CONSTRAINT raw_links_pk and the same for raw_fk.
After you delete the records, first do a VACUUM ANALYZE raw_links (or VACUUM FULL raw_links if you want to reclaim disk space), to update the table statistics.
Then finally rebuild the constraints with ALTER TABLE ADD CONSTRAINT ....
For the example.
Schema: source, Table: finalsales, Constrait: finalsales_pkey, Column: order_id.
--Disable Primary Key
ALTER TABLE source."finalsales" DROP CONSTRAINT finalsales_pkey;
--Enable Primary Key
ALTER TABLE source."finalsales"
ADD CONSTRAINT finalsales_pkey PRIMARY KEY ( order_id );

T-SQL foreign key check constraint

When you create a foreign key constraint in a table and you create the script in MS SQL Management Studio, it looks like this.
ALTER TABLE T1 WITH CHECK ADD CONSTRAINT FK_T1 FOREIGN KEY(project_id)
REFERENCES T2 (project_id)
GO
ALTER TABLE T1 CHECK CONSTRAINT FK_T1
GO
What I don't understand is what purpose has the second alter with check constraint.
Isn't creating the FK constraint enough? Do you have to add the check constraint to assure reference integrity ?
Another question: how would it look like then when you'd write it directly in the column definition?
CREATE TABLE T1 (
my_column INT NOT NULL CONSTRAINT FK_T1 REFERENCES T2(my_column)
)
Isn't this enough?
First it creates the constraint and here you can specify whether data allready in the table should be checked or not against your new constraint. WITH { CHECK | NOCHECK }
The second part specifies that the constraint is enabled. ALTER TABLE TableName { CHECK | NOCHECK } CONSTRAINT ConstraintName
The second statement is compelled by the "WITH CHECK" in the first statement. There is a setting you can toggle to not do this.