How to change value of a primary key when its a foreign key reference in another table in postgresql - postgresql

I have a table user_type and user_type_id is the primary key of that table and I have another table user_details where user_type_id is a reference of the foreign key.
I want to change the id value of the user_type_id column.

First update user_details to set the foreign key column to NULL for the rows that depend on the primary key, then update user_type, then change the rows in user_details to the updated value.
You can make this easier in two ways:
define the foreign key with ON UPDATE CASCADE, then this happens automatically
define the foreign key as DEFERRABLE, the you can defer the check to the end of the transaction

Related

use one part of composite primary key as foreign key

I'm using PostgreSQL.
I have a table accounts with account_id as the primary key. I also have a second table called relations with a composite primary key (follower_id, following_id). Each relation must be unique.
ALTER TABLE accounts ADD CONSTRAINT users_pk PRIMARY KEY (account_id);
ALTER TABLE relations ADD CONSTRAINT relations_pk PRIMARY KEY (follower_id, following_id);
I want to create a foreign key constraint from follower_id (relations) -> account_id (accounts), and the same with following_id.
ALTER TABLE relations ADD CONSTRAINT follower_id_fk FOREIGN KEY (follower_id) REFERENCES accounts (account_id) ON DELETE CASCADE
This foreign key is not accepted by the database. I get the following error:
ERROR: insert or update on table "relations" violates foreign key constraint "follower_id_fk"
DETAIL: Key (follower_id)=(4) is not present in table "accounts".
I understand this, because it's a composite primary key.
What I want to achieve:
When an account is deleted, I want to delete all the records where the account_id is the follower_id (ON DELETE CASCADE) AND where it is the following_id.
I could do this in my nodejs code or with a trigger function, but I don't know what will be the best performance-wise. Does anyone knows a/the best solution?

Dropping unique constraint on foreign key reference of junction table

I'm creating a database in PostgreSQL and want to include a many-to-many relationship between the tables. The two tables I want to include are as follows:
CREATE TABLE "meter" (
"id" integer PRIMARY KEY,
"nmi" integer,
"next_scheduled_read_date" timestamp
);
CREATE TABLE "register" (
"id" text PRIMARY KEY,
"value" text
);
The many-to-many relationship I want to have is between meter id and register id. I have then created the junction table below:
CREATE TABLE "meter_registers" (
"meter_id" integer NOT NULL,
"register_id" text NOT NULL,
PRIMARY KEY ("meter_id", "register_id"),
FOREIGN KEY ("meter_id") REFERENCES "meter" ("id") ON UPDATE CASCADE,
FOREIGN KEY ("register_id") REFERENCES "register" ("id") ON UPDATE CASCADE
);
I then want to create a table that references the meter_id and register_id values from the junction table above which is structured as follows:
CREATE TABLE "demand_data" (
"upload_id" integer PRIMARY KEY,
"nmi" integer,
"meter" integer,
"register" text,
"start" timestamp,
"end" timestamp,
"duration" Time,
"demand" double precision
);
Where the meter and register reference the corresponding junction table columns. However, as the values of the junction table will not be unique I can't simply add a foreign key for the meter and register columns so I run into an error when I run the following:
ALTER TABLE "demand_data" ADD FOREIGN KEY ("meter") REFERENCES "meter_registers" ("meter_id");
ALTER TABLE "demand_data" ADD FOREIGN KEY ("register") REFERENCES "meter_registers" ("register_id");
ERROR: there is no unique constraint matching given keys for referenced table "meter_registers"
Is there a way to possibly reference the junction table columns in the demand_data table without the foreign key constraint? I know it's possible to do with a separate query once some data has been added using inner joins however, is it possible to do it through database table set up?
Yes. A compound foreign key.
ALTER TABLE "demand_data"
ADD FOREIGN KEY ("meter","register")
REFERENCES "meter_registers"( "meter_id", "register_id");
Note: Not directly related you should avoid those dreaded double quotes.
If demand_data references meter_registers, it should reference its primary key. So add a single foreign key constraint on both columns.
If you want two separate foreign keys,you should probably reference meter and register directly.

Can a composite foreign key reference a composite primary key and not have all the values NOT match (Oracle)? And in the same table?

This is an existing table in Production. Adding a new row with a unique primary key causes failure to enable the foreign key with 'parent does not exist' but the data is there. PK does not prevent insert so I know it's unique.
ALTER TABLE tableA ADD (CONSTRAINT tableA_PK
PRIMARY KEY
(SEGMENT, STEP)
USING INDEX tableA.tableA_PK
ENABLE VALIDATE;
ALTER TABLE tableA ADD (
CONSTRAINT tableA_FK
FOREIGN KEY (SEGMENT, PREDECESSOR_STEP)
REFERENCES tableA (SEGMENT, STEP)
ENABLE VALIDATE);
Note: PREDECESSOR_STEP will never be = to STEP. SEGMENT, PREDECESSOR_STEP each have their own non-unique index:
SEGMENT - unique index
STEP - unique index
STEP - also has a non-unique index
PREDECESSOR_STEP - non-unique index
A primary key values look like:
AEM CAL_NVR_ID
The foreign key values:
AEM CAL_NVR
When I try to insert a row with these exact values I am getting : 'parent does not exist' when enabling the fk constraint.

How to handle foreign key in postgresql

I am new to postgresql..I am creating a database which contains table “user” with columns “Name”,”Sum”,”id”(which is a serial primary key)
I want to input data only in columns Name and Sum since id is a serial PK
The column “id” is a foreign key in another table “account”, so when I am trying to input data in the table it is telling me I am violating the foreign key constraint
Here is the code:
INSERT INTO public.”user”(“Name”,”Sum”)
VALUES (‘Tasneem’,400);
It is telling me
Insert or update on table “user” violates foreign key constraint “user_Sum_fkey”
Key (Sum)=(400) is not present in table account

Will a primary key index serve as an index for a foreign key when fk columns are subset of pk?

I have a table where part of the primary key is a foreign key to another table.
create table player_result (
event_id integer not null,
pub_time timestamp not null,
name_key varchar(128) not null,
email_address varchar(128),
withdrawn boolean not null,
place integer,
realized_values hstore,
primary key (event_id, pub_time, name_key),
foreign key (email_address) references email(address),
foreign key (event_id, pub_time) references event_publish(event_id, pub_time));
Will the index generated for the primary key suffice to back the foreign key on event_id and pub_time?
Yes.
Index A,B,C
is good for:
A
A,B
A,B,C (and any other combination of the full 3 fields, if default order is unimportant)
but not good for other combinations (such as B,C, C,A etc.).
It will be useful for the referencing side, such that a DELETE or UPDATE on the referenced table can use the PRIMARY KEY of the referencing side as an index when performing checks for the existence of referencing rows or running cascade update/deletes. PostgreSQL doesn't require this index to exist at all, it just makes foreign key constraint checks faster if it is there.
It is not sufficient to serve as the unique constraint for a reference to those columns. You couldn't create a FOREIGN KEY that REFERENCES player_result(event_id, pub_time) because there is no unique constraint on those columns. That pair can appear multiple times in the table so long as each pair has a different name_key.
As #xagyg accurately notes, the unique b-tree index created by the foreign key reference is also only useful for references to columns from the left of the index. It could not be used for a lookup of pub_time, name_key or just name_key, for example.