Postgres Unique constraint based column value - postgresql

CREATE TABLE employee (
id varchar(40) NOT NULL,
legacy_id varchar(40) NOT NULL,
short_name varchar(255) NULL,
is_deleted bool NOT NULL DEFAULT false,
CONSTRAINT employee_pkey PRIMARY KEY (id)
)
I want to plan for unique constraint like this
The table must have these constraint
1. Unique constraint is required on column 'legacy_id' and 'is_deleted = false'. Its okay to have multiple values with legacy_id and is_deleted = true.
Is there any way to achieve this

You cannot have a constraint for that, but a partial unique index will do just as well:
CREATE UNIQUE INDEX ON employee (legacy_id)
WHERE is_deleted;

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.

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?

with migration to fill slug with default value

In my Laravel 5.6/PostgreSQL 10.5 application
I have 2 tables :
CREATE TABLE public.rt_genres (
id serial NOT NULL,
published bool NULL DEFAULT false,
created_at timestamp NOT NULL DEFAULT now(),
updated_at timestamp NULL,
CONSTRAINT rt_genres_pkey PRIMARY KEY (id)
)...
CREATE TABLE public.rt_genre_translations (
id serial NOT NULL,
genre_id int4 NOT NULL,
"name" varchar(100) NOT NULL,
description text NOT NULL,
created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
locale varchar(2) NOT NULL,
CONSTRAINT genre_translations_genre_id_locale_unique UNIQUE (genre_id, locale),
CONSTRAINT rt_genre_translations_pkey PRIMARY KEY (id),
CONSTRAINT genre_translations_genre_id_foreign FOREIGN KEY (genre_id) REFERENCES rt_genres(id) ON DELETE CASCADE
)
I need to add slug field in first rt_genres table
with migration rule:
$table->string('slug', 105)->unique();
and got error :
: Unique violation: 7 ERROR: could not create unique index "genres_slug_unique"
DETAIL: Key (slug)=(id) is duplicated.")
1)If there is a way to assign in migration some unique default value, like = id
->default('rt_genres.id')
?
2) That would be cool to assign to slug value from public.rt_genre_translations.name as I use
"cviebrock/eloquent-sluggable": "^4.5" plugin in my app ? Can I do it ?
Thank you!
You can only get the default value from a different column with a trigger (SO answer).
You can make the column nullable:
$table->string('slug', 105)->nullable()->unique();
Or you create the column, insert unique values and then create the index:
Schema::table('rt_genres', function($table) {
$table->string('slug', 105);
});
DB::table('rt_genres')->update(['slug' => DB::raw('"id"')]);
Schema::table('rt_genres', function($table) {
$table->unique('slug');
});

Find cause of error "constraint xxxx is not a foreign key constraint" in Postgresql

I have defined these tables:
CREATE TABLE "public".category (id BIGSERIAL NOT NULL, name varchar(255) NOT NULL, PRIMARY KEY (id));
CREATE UNIQUE INDEX category_name ON "public".category (name);
CREATE TABLE "public".clusters (id BIGSERIAL NOT NULL, name varchar(255) NOT NULL, PRIMARY KEY (id));
CREATE INDEX clusters_name ON "public".clusters (name);
CREATE TABLE "public".keywords (id BIGSERIAL NOT NULL, text varchar(255) NOT NULL, category_id int8 NOT NULL, top_results int4, cluster_id int8, month_requests int4, click_cost float8, PRIMARY KEY (id));
CREATE INDEX keywords_text ON "public".keywords (text);
ALTER TABLE "public".keywords ADD CONSTRAINT FKkeywords488682 FOREIGN KEY (cluster_id) REFERENCES "public".clusters (id);
ALTER TABLE "public".keywords ADD CONSTRAINT FKkeywords446526 FOREIGN KEY (category_id) REFERENCES "public".category (id) ON UPDATE CASCADE ON DELETE CASCADE;
added one record to category table:
INSERT INTO "public".category(id, name) VALUES (1, 'Test');
And now when I try to add record to keyword table
insert into "public"."keywords" ( "category_id", "text") values ( 1, 'testkey')
I got error:
ERROR: constraint 16959 is not a foreign key constraint
When I do
select * FROM pg_constraint;
I can't see constraint with this id. I can't understand what is the cause of this problem.