I have a fields.Char attribute “identification_id”, That field must have 11 characters. How can I add a _sql_constraints to check the length of that field and ensure it should be 11 ?
You can use the Check Constraints with length function
_sql_constraints = {
('check_name', 'check(length(name)>10)', 'name must be at least 11 characters')
}
Edit:
The constraint will not be added if you have already a record that did not satisfy it:
ERROR demo odoo.sql_db: bad query: ALTER TABLE "hr_employee" ADD CONSTRAINT "hr_employee_check_name" check(length(name)>10)
ERROR: ERROR: The verification constraint "hr_employee_check_name" is broken by a line
Related
I want to add a column which's also a primary key if it doesn't already exist on the table. If I do a simple
ALTER TABLE webinars_identities ADD COLUMN IF NOT EXISTS id uuid
It will work but if I do
ALTER TABLE webinars_identities ADD COLUMN IF NOT EXISTS id uuid PRIMARY KEY DEFAULT uuid_generate_v4();
It says it skips the alter table, but for some reason crashes right after:
NOTICE: column "id" of relation "webinars_identities" already exists, skipping
ERROR: multiple primary keys for table "webinars_identities" are not allowed
My original working query was
ALTER TABLE webinars_identities id uuid PRIMARY KEY DEFAULT uuid_generate_v4();
But this is not repeatable without error.
What am I doing wrong here ?
Handle it using duplicate_column exception and issue a notice, because someone rightly said that errors should never pass silently.
DO $body$
BEGIN
ALTER TABLE atable ADD COLUMN id int primary key; --DEFAULT uuid_generate_v4()
EXCEPTION
WHEN duplicate_column THEN
RAISE NOTICE 'ERROR: %,%',SQLSTATE,SQLERRM;
END $body$;
This will work the first time and does not fail on all following attempts, but gives you a message. All other errors if found in your statement will be raised as exceptions.
NOTICE: ERROR: 42701,column "id" of relation "atable" already exists
DO
Try this.
DO $$ BEGIN TABLE atable ADD COLUMN IF NOT EXISTS id int primary key ; exception when others then null ; END$$;
It's a bug in postgres https://www.postgresql.org/message-id/13277.1566920001%40sss.pgh.pa.us
Will be fixed in v13.0, hopefully.
Is there is a possibility to make SQL constraint for the boolean field? I want to make a constraint that will check all record and only 1 record can have boolean field checked
Try using this,
_sql_constrainst =[('your const. id', 'check(your_bool_field != Null)', 'Your validation msg')]
For a test tomorrow we're told to name our constraints
I know it's possible to create a constraint when you use ALTER TABLE
but can you add a name to a not null constraint when you CREATE TABLE?
f.e.
CREATE TABLE test (
test1 VARCHAR
CONSTRAINT nn_test1 NOT NULL (test1)
)
I get an error when trying to run this query. Am I writing it wrong?
The error I get is
ERROR: syntax error at or near "NOT"
LINE 3: CONSTRAINT nn_test1 NOT NULL (test1))
^
SQL state: 42601
Character: 56
You have two options to define a named not null constraint:
Inline with the column:
CREATE TABLE test
(
test1 VARCHAR CONSTRAINT nn_test1 NOT NULL,
test2 integer --<< no comma because it's the last column
);
Or at the end of columns as an out-of-line constraint. But then you need a check constraint:
CREATE TABLE test
(
test1 VARCHAR,
test2 integer, --<< comma required after the last column
constraint nn_test1 check (test1 is not null)
);
This has become irrelevant, since you're not using SQL Server
First of all, you should always specify a length for a VARCHAR. Not doing so (in SQL Server variables, or parameters) may result in a string of just exactly ONE character in length - typically NOT what you want.
Then, you need to just specify the NOT NULL - there's no need to repeat the column name (actually this is the error) - if you're specifying the CONSTRAINT "inline" with the column definition (which is a perfectly legal and in my opinion the preferred way of doing this).
Try this code:
CREATE TABLE test
(
test1 VARCHAR(50)
CONSTRAINT nn_test1 NOT NULL
)
At least this is the CREATE TABLE statement that works in T-SQL / SQL Server - not sure about PostgreSQL (don't know it well enough, don't have it at hand to test right now).
I, a_horse_with_no_name, the two syntax:
constraint nn_test1 check (test1 is not null)
and
test1 VARCHAR CONSTRAINT nn_test1 NOT NULL
are equivalent ? performance correctly ecc.
Because in first case the SQL server exception return the name nn_test so the system know exactly error.
I tried to insert some data in a database with postgresql but still showing the same message:
ERROR: new row for relation "empleados" violates check constraint
"ck_empleados_documento" DETAIL: Failing row contains (13, 22222222,
f, Lopez, Ana, Colon 123, 1, 2, casado , 1990-10-10).
I do not know where or what the error is nor did I find anything that solved this. This is what i try to insert:
insert into empleados (documento, sexo, apellido, nombre, domicilio, idSecc, cantidadhijos, estadocivil, fechaingreso) values('22222222','f','Lopez','Ana','Colon 123',1,2,'casado','1990-10-10');
and this is the structure of the table:
CREATE TABLE public.empleados
(
idempleado integer NOT NULL DEFAULT nextval('empleados_idempleado_seq'::regclass),
documento character(8),
sexo character(1),
apellido character varying(20),
nombre character varying(20),
domicilio character varying(30),
idsecc smallint NOT NULL,
cantidadhijos smallint,
estadocivil character(10),
fechaingreso date,
CONSTRAINT pk_empleados PRIMARY KEY (idempleado),
CONSTRAINT fk_empleados_idsecc FOREIGN KEY (idsecc)
REFERENCES public.puestos (idpuesto) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION,
CONSTRAINT uq_empleados_documento UNIQUE (documento),
CONSTRAINT ck_empleados_documento CHECK (documento ~~ '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'::text),
CONSTRAINT ck_empleados_estadocivil CHECK (estadocivil = ANY (ARRAY['casado'::bpchar, 'divorciado'::bpchar, 'soltero'::bpchar, 'viudo'::bpchar])),
CONSTRAINT ck_empleados_hijos CHECK (cantidadhijos >= 0),
CONSTRAINT ck_empleados_sexo CHECK (sexo = ANY (ARRAY['f'::bpchar, 'm'::bpchar]))
)
The error message says your row violates check constraint "ck_empleados_documento".
ck_empleados_documento is defined as
CONSTRAINT ck_empleados_documento CHECK (documento ~~ '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'::text)
According to https://www.postgresql.org/docs/current/static/functions-matching.html#FUNCTIONS-LIKE:
The operator ~~ is equivalent to LIKE
So your constraint really means
documento LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'::text
From the same page:
stringLIKEpattern
If pattern does not contain percent signs or underscores, then the pattern only represents the string itself
Your pattern doesn't contain % or _, so it is equivalent to
documento = '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
This can never be true because documento is only 8 characters long.
You probably want to do this instead:
documento SIMILAR TO '[0-9]{8}'
SIMILAR TO uses SQL regexes and understands character classes such as [0-9].
I think your ck_empleados_documento should be written like this:
CONSTRAINT ck_empleados_documento CHECK (documento ~ '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'::text),
Explanation: According to the Postgres Documentation:
The operator ~~ is equivalent to LIKE
If you want pattern matching you need to use Operators:
~ Matches regular expression, case sensitive
~* Matches regular expression, case insensitive
!~ Does not match regular expression, case sensitive
!~* Does not match regular expression, case insensitive
This answer is for those who get this error even when they haven't explicitly defined any constraint. In my case I'm using django and one of my models has a field defined as a PositiveBigIntegerField, so the error occurred when some logic tried to set the field's value to a negative number. So check your model/table definitions to make sure you're not violating implicit constraints that exist without your knowledge.
I am trying to define a new domain "rating_int" that I would be able to use in the table "Review". Anytime I try to execute this query, it returns this message:
ERROR: column "rating_int" does not exist
********** Error **********
ERROR: column "rating_int" does not exist
SQL state: 42703
I followed the exact same code format as the postgresql example and I do not know why my code is returning an error.
CREATE DOMAIN rating_int AS INTEGER
CHECK(rating_int > 0 AND rating_int <=10);
CREATE TABLE Review
(
paper_id INTEGER,
rv_email VARCHAR(55) NOT NULL,
reccomendation TEXT,
a_comments TEXT,
c_comments TEXT,
technical_merit rating_int,
readability rating_int,
orginality rating_int,
relevance rating_int,
PRIMARY KEY(paper_id, rv_email),
FOREIGN KEY(paper_id) REFERENCES Paper
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(rv_email) REFERENCES Reviewer
ON DELETE SET NULL ON UPDATE CASCADE
);
You use value, not the name of the domain. Like this:
CREATE DOMAIN rating_int AS INTEGER
CONSTRAINT chk_rating_int CHECK (value > 0 AND value <= 10);
You don't actually need to give the constraint a name -- your error was rating_int instead of value. So this works:
CREATE DOMAIN rating_int AS INTEGER
CHECK (value > 0 AND value <= 10);
However, I think it is a good idea to give constraints names.
Also, you might want to make the type a smallint or decimal(2), if you want to save on space.