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

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.

Related

Execute procedure automatically

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?

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);

Error Code: 1822. Failed to add the foreign key constraint. Missing index for constraint 'questions_ibfk_1' in the referenced table 'category'

cannot add foreign key constraint to table
create table users
(
user_id int auto_increment primary key not null,
username varchar(50) unique null ,
email varchar(50) unique ,
passwords varchar(50) not null,
login_status boolean not null
);
create table category (
category_id int primary key not null,
category_name varchar(50) not null
);
create table answers (
id_answer int auto_increment primary key not null,
answer boolean not null
);
create table questions (
question_id int primary key not null,
category_name varchar(50) not null,
content varchar(50) not null ,
foreign key (category_name) references category (category_name)
);
You get this error because there's no index on category_name in the category table. Change that CREATE statement as follows:
create table category (
category_id int primary key not null,
category_name varchar(50) not null,
KEY category_name_index (category_name)
);
From the docs (8.0 version, but the statement is true for older versions):
MySQL requires indexes on foreign keys and referenced keys so that foreign key checks can be fast and not require a table scan. In the referencing table, there must be an index where the foreign key columns are listed as the first columns in the same order. Such an index is created on the referencing table automatically if it does not exist. This index might be silently dropped later, if you create another index that can be used to enforce the foreign key constraint. index_name, if given, is used as described previously.
Also, you're using a varchar(50) as your foreign key, which is not usually a great idea for a variety of reasons. You probably want to use a numeric value, such as category_id, instead.

The value of one column can not contain in the other column and vice versa

I have the following structure:
CREATE TABLE users (
id bigserial PRIMARY KEY,
parent_id bigint REFERENCES users(id),
left_id bigint REFERENCES users(id) UNIQUE,
right_id bigint REFERENCES users(id) UNIQUE,
);
left_id value can not contain in any row of right_id
right_id value can not contain in any row of right_id
How to create a constraint for this scenario?

Primary key for multiple columns in PostgreSQL?

How to provide primary key for multiple column in a single table using PostgreSQL?
Example:
Create table "Test"
(
"SlNo" int not null primary key,
"EmpID" int not null, /* Want to become primary key */
"Empname" varchar(50) null,
"EmpAddress" varchar(50) null
);
Note: I want to make "EmpID" also a primary key.
There can only be one primary key per table - as indicated by the word "primary".
You can have additional UNIQUE columns like:
CREATE TABLE test(
sl_no int PRIMARY KEY, -- NOT NULL due to PK
emp_id int UNIQUE NOT NULL,
emp_name text,
emp_addr text
);
Columns that are (part of) the PRIMARY KEY are marked NOT NULL automatically.
Or use a table constraint instead of a column constraint to create a single multicolumn primary key. This is semantically different from the above: Now, only the combination of both columns must be unique, each column can hold duplicates on its own.
CREATE TABLE test(
sl_no int, -- NOT NULL due to PK below
emp_id int , -- NOT NULL due to PK below
emp_name text,
emp_addr text,
PRIMARY KEY (sl_no, emp_id)
);
Multicolumn UNIQUE constraints are possible, too.
Aside: Don't use CaMeL-case identifiers in Postgres. Use legal, lower-case identifiers so you never have to use double-quotes. Makes your life easier. See:
Are PostgreSQL column names case-sensitive?
In case you want to specify the name of the primary key constraint:
CREATE TABLE test(
sl_no int not null,
emp_id int not null,
emp_name text,
emp_addr text,
constraint pk_test primary key (sl_no, emp_id)
);
Source: https://www.postgresqltutorial.com/postgresql-primary-key/