Execute procedure automatically - postgresql

I have this table
create table preƱadas(
hierro varchar(15) NOT NULL,
hierro_toro varchar (30) NOT NULL,
fecha_esperada_parto timestamp,
observaciones varchar(200),
primary key (hierro),
foreign key (hierro) references animales,
foreign key (hierro_toro) references animales (hierro)
);
i would like to eliminate a record automatically from it when now() is one month past fecha_esperada_parto
Any ideas how to do it?

Related

Postgres violates not null constraint, even when there isn't one

Hey I have a Postgres database that has a Schema with
CREATE TABLE Mentor (
mentor_ID serial unique,
person_ID serial not null unique,
career_history varchar(255) not null,
preferred_communication varchar(50) not null,
mentoring_preference varchar(50) not null,
linked_in varchar(100) not null,
capacity int not null,
feedback_rating int,
feeback_comment varchar(255),
PRIMARY KEY (mentor_ID),
CONSTRAINT fk_person FOREIGN KEY (person_ID) REFERENCES Person(person_ID)
);
CREATE TABLE Mentee(
mentee_ID integer not null unique,
mentor_ID serial references Mentor(mentor_ID),
person_ID serial not null unique,
study_year int,
motivation varchar(50),
interests varchar(255),
random_match boolean default false,
PRIMARY KEY (mentee_ID),
CONSTRAINT fk_person FOREIGN KEY (person_ID) REFERENCES Person(person_ID)
);
With this, i expect to be able to enter null values for mentor_ID in my database but when I enter the query
insert into mentee(mentee_ID, mentor_ID, person_ID) VALUES (12313, null, 1)
I get the violation
ERROR: null value in column "mentor_id" of relation "mentee" violates not-null constraint
I was wondering how I could make it so I can insert null values for mentor_ID? I dont have it as not null in the table but it still says violating not null constraint.
Thank you
Because serial is not null.
serial is...
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
Note the integer not null. This is because serial is to be used for primary keys, not foreign keys. Foreign keys are always assigned, they don't need to auto increment.
Use a plain integer.
mentor_ID integer references Mentor(mentor_ID)
Same for your other foreign keys.
Notes:
identity is the SQL standard way to do auto incremented primary keys.
You don't need to declare primary keys as unique, primary keys are already unique.
Unless there's a specific reason to constrain the size of a text field, use text. varchar and text only use the necessary amount of space for each row. "foo" will take the same amount of space in varchar(10) as in varchar(255). For example, there's no particular reason to limit the size of their linked in nor motivation.

Postgresql - delete on cascade not deleting from a child table

I have tables master_bill and master_bill_order_leg and order_leg.
MasterBill and OrderLeg have many to many relationship.
This is the quick documentation from IntelliJ for the DB tables.
Table master_bill:
create table master_bill
(
id bigint not null
primary key,
mb_no bigint not null,
created_by text not null,
updated_by text not null,
created_at timestamp with time zone default now() not null,
updated_at timestamp with time zone default now() not null
);
Table master_bill_order_leg:
create table master_bill_order_leg
(
mb_id bigint
references master_bill
on delete cascade,
order_leg_id bigint
references order_leg
on delete cascade,
constraint master_bill_order_mb_id_order_leg_id_key
unique (mb_id, order_leg_id)
);
Table order_leg:
create table order_leg
(
id bigserial
primary key,
created_by text not null,
updated_by text not null,
created_at timestamp with time zone default now() not null,
updated_at timestamp with time zone default now() not null,
constraint order_leg_unique_c
unique (flight_id, flight_date, departure_iata, arrival_iata)
);
I have set the foreign keys and they look like this:
Table master_bill_order_leg
master_bill_order_leg_mb_id_fkey (mb_id) -> master_bill(id)
master_bill_order_leg_order_leg_id_fkey (order_leg_id) -> order_leg(id)
I thought that if I delete a row from the parent master_bill table that all relevant rows from the child table master_bill_order_leg would be deleted too because of foreign keys that are set with on delete cascade. So, I have tried with deleting a row from master_bill table:
DELETE
FROM master_bill
WHERE id = :mbId
But, then I get an error:
org.postgresql.util.PSQLException: ERROR: update or delete on table
"master_bill" violates foreign key constraint
"master_bill_order_leg_mb_id_fkey" on table
"master_bill_order_leg" Detail: Key (id)=(1076) is
still referenced from table "master_bill_order_leg".
Why do I get this error, what am I doing wrong here?
If I run this query directly from the query console then a row is deleted from the table master_bill and a child table master_bill_order_leg.

Postgres - Create or replace table

I have a table that is already created with data and I need only modify the schema to add some constraints .
my created tabled schema
CREATE TABLE public.note (
note_id bigint NOT NULL,
confidential boolean NOT NULL,
follow_up_date date,
notification_date date,
priority integer NOT NULL,
recurring_follow_up_interval interval,
status character varying(255) NOT NULL,
create_date timestamp with time zone,
deleted boolean NOT NULL,
last_modified_date timestamp with time zone,
time_spent integer,
title text,
version bigint NOT NULL,
assigned_to_id bigint,
note_category_id bigint NOT NULL,
created_by_id bigint,
last_modified_by_id bigint
);
what I need to match
create table note
(
note_id bigint default nextval('note_id_seq'::regclass) not null,
confidential boolean not null,
follow_up_date date,
notification_date date,
priority integer default 0 not null,
recurring_follow_up_interval interval,
status varchar(255) not null,
create_date timestamp with time zone,
deleted boolean default false not null,
last_modified_date timestamp with time zone,
time_spent integer,
title text,
version bigint default 0 not null,
assigned_to_id bigint,
note_category_id bigint not null,
created_by_id bigint,
last_modified_by_id bigint,
constraint note_pkey
primary key (note_id),
constraint fk_4nrhbn2j8j2vqqh78vleef9xr
foreign key (created_by_id) references admin_user,
constraint fk_eid7x7jfvjoe1h5tnyouhmqpa
foreign key (assigned_to_id) references admin_user,
constraint fk_oi5l4dg3sg5ep5neagmvp9r7o
foreign key (note_category_id) references note_category,
constraint fk_tk8ncyc0hmdi3gfh67b4jyu3l
foreign key (last_modified_by_id) references admin_user
);
as you can see it missing all defaults + all constraint to the other tables
any way to copy the intended schema to the created one without loosing the data
I am using Postgres 12
UPDATE
I know I could use alter to modify some columns but it will be a long process for me as there are many columns and I got more than 300 tables that have the same case
I manually alter one column to add sequence but I need easier way to do that for all columns
ALTER TABLE ONLY note ALTER COLUMN note_id SET DEFAULT nextval('note_id_seq'::regclass);

Does postgresql require unique constraint names when defining FOREIGN KEYS

Here is my schema for database tables:
CREATE TABLE users (
user_id INTEGER NOT NULL,
device_id INTEGER,
user_points INTEGER,
cookie VARCHAR,
PRIMARY KEY (user_id)
);
CREATE TABLE admins (
admin_id INTEGER NOT NULL,
username VARCHAR,
password VARCHAR
);
CREATE TABLE admin_adventure (
adventure_id INTEGER NOT NULL,
admin_id INTEGER,
PRIMARY KEY (adventure_id)
);
CREATE TABLE adventures (
adventure_id INTEGER NOT NULL,
prize_id INTEGER,
novella_id INTEGER,
PRIMARY KEY (adventure_id)
);
Here I'm trying to define FOREIGN KEYS:
ALTER TABLE admin_adventure ADD FOREIGN KEY ( admin_id ) REFERENCES admins ( admin_id );
ALTER TABLE admin_adventure ADD FOREIGN KEY ( adventure_id ) REFERENCES adventures ( adventure_id );
And here is the error I get when trying to migrate with Flyway:
ERROR: there is no unique constraint matching given keys for
referenced table "admins"
Can someone explain what I'm doing wrong and why I get this error?
The error message is complaining that you are trying to link a foreign key to a column in another table which is not unique (e.g. a primary key). Try making the admin_id column in the admins table a primary key:
CREATE TABLE admins (
admin_id INTEGER NOT NULL,
username VARCHAR,
password VARCHAR,
PRIMARY KEY (admin_id)
);
Like the documentation says:
A foreign key must reference columns that either are a primary key or form a unique constraint.
So you must either
ALTER TABLE admins ADD PRIMARY KEY (admin_id);
or
ALTER TABLE admins ADD UNIQUE (admin_id);

Postgres before insert trigger using sequence from another table

Using Postgres, what I would like to achieve is to be able to have many different instrument types, with corresponding [TYPE].instrument tables, which all have a unique ID in the table, but also reference a unique ID in the instrument.master table. I have the following:
create schema instrument
CREATE TABLE instrument.type (
id smallserial NOT NULL,
name text not null,
code text not null,
CONSTRAINT pk_instrument_type PRIMARY KEY (id)
);
ALTER TABLE instrument.type ADD CONSTRAINT unq_instrument_type_code UNIQUE(code);
ALTER TABLE instrument.type ADD CONSTRAINT unq_instrument_type_name UNIQUE(name);
insert into instrument.type (name, code) values ('futures', 'f');
CREATE TABLE instrument.master (
id serial NOT NULL,
type smallint not null references instrument.type (id),
timestamp timestamp with time zone not null,
CONSTRAINT pk_instrument_master PRIMARY KEY (id)
);
CREATE TABLE futures.definition (
id smallserial NOT NULL,
code text not null,
CONSTRAINT pk_futures_definition PRIMARY KEY (id)
);
ALTER TABLE futures.definition ADD CONSTRAINT unq_futures_definition_code UNIQUE(code);
insert into futures.definition (code) values ('ED');
CREATE TABLE futures.instrument (
id smallserial NOT NULL,
master serial not null references instrument.master (id),
definition smallint not null references futures.definition (id),
month smallint not null,
year smallint not null,
CONSTRAINT pk_futures_instrument PRIMARY KEY (id),
check (month >= 1),
check (month <= 12),
check (year >= 1900)
);
ALTER TABLE futures.instrument ADD CONSTRAINT unq_futures_instrument UNIQUE(definition, month, year);
CREATE OR REPLACE FUNCTION trigger_master_futures()
RETURNS trigger AS
$BODY$
BEGIN
insert into instrument.master (type, timestamp)
select id, current_timestamp from instrument.type where code = 'f';
NEW.master := currval('instrument.master_id_seq');
RETURN NEW;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
create trigger trg_futures_instrument before insert on futures.instrument
for each row
execute procedure trigger_master_futures();
I then test with:
insert into futures.instrument (definition, month, year)
select id, 3, 2015 from futures.definition where code = 'ED';
Everything works almost as I would like it to. The only issue is that somehow, instrument.master.id ends up being one more than futures.instrument.master. I am not sure what I need to do to achieve the behavior I want, which is that whenever an entry is inserted into futures.instrument, an entry should be inserted into instrument.master, and the id entry of the latter should be inserted into the master entry of the former. I actually think it should have failed since the foreign key relationship is violated somehow.
As it turns out, everything was correct. The issue was that in futures.instrument, the type of the master column is serial, and it should have been int.