Insert jsonb into postgresql - activejdbc

I want to create an object and save it ionto the DB
Log l = new Log();
l.setTimestamp("creation_date", Util.getCurrentTimestamp());
l.setString("app_name", "name");
l.setString("log_type", "type");
l.setLong("user_id", 9l);
l.setLong("module_element_id", 9);
l.set("info", JsonHelper.toJsonString("{}"));
l.save();
I've tried mutiple silution but always get this error:
ERROR: column "info" is of type jsonb but expression is of type character varying
How to insert a jsonb?
edit (DDL):
-- Table: public.log
-- DROP TABLE public.log;
CREATE TABLE public.log
(
id bigint NOT NULL DEFAULT nextval('log_id_seq'::regclass),
creation_date timestamp without time zone,
app_name text,
log_type text,
user_id bigint,
module_element_type bigint,
info jsonb,
CONSTRAINT log_pkey PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE public.log
OWNER TO postgres;

This implementation is missing in the framework currently. It was already reported in https://github.com/javalite/activejdbc/issues/640. If you can help tracking down Postgres documentation for all the Postgres data types where this syntax is used with PreparedStatement:
UPDATE my_table SET status = ?::status_type WHERE id = ?
I will then be in a position to quickly implement it for the PostgreSQL dialect: https://github.com/javalite/activejdbc/blob/master/activejdbc/src/main/java/org/javalite/activejdbc/dialects/PostgreSQLDialect.java
Update Jan 4 2022:
The implementation was added to the SNAPSHOT-3.0 and will make it to a next release 3.0 for Java 16.
You can see the discussion here: https://github.com/javalite/javalite/issues/640

Related

Why is the column not altering when I try to convert it to UUID?

I have a primary key column in my SQL table in PostgreSQL named "id". It is a "bigseries" column. I want to convert the column to a "UUID" column. It entered the below command in the terminal:
alter table people alter column id uuid;
and
alter table people alter column id uuid using (uuid_generate_v4());
but neither of them worked.
In both tries I got the error message
ERROR: syntax error at or near "uuid"
LINE 1: alter table people alter column id uuid using (uuid_generate...
What is the correct syntax?
First of all uuid_generate_v4() is a function which is provided by an extension called uuid-ossp. You should have install that extension by using;
CREATE EXTENSION uuid-ossp;
Postgresql 13 introduced a new function which does basically the same without installing extension. The function is called gen_random_uuid()
Suppose that we have a table like the one below;
CREATE TABLE people (
id bigserial primary key,
data text
);
The bigserial is not a real type. It's a macro which basically creates bigint column with default value and a sequence. The default value is next value of that sequence.
For your use case, to change data type, you first should drop the old default value. Then, alter the type and finally add new default value expression. Here is the sample:
ALTER TABLE people
ALTER id DROP DEFAULT,
ALTER id TYPE uuid using (gen_random_uuid() /* or uuid_generate_v4() */ ),
ALTER id SET DEFAULT gen_random_uuid() /* or uuid_generate_v4() */ ;
CREATE TABLE IF NOT EXISTS people (
id uuid NOT NULL CONSTRAINT people_pkey PRIMARY KEY,
address varchar,
city varchar(255),
country varchar(255),
email varchar(255),
phone varchar(255)
);
This is the correct syntax to create table in postgres SQL, it's better to do these constraints at beginning to avoid any error.
For using alter command you would do the following:
ALTER TABLE customer ADD COLUMN cid uuid PRIMARY KEY;
Most of errors that you could find while writing command either lower case or undefined correct the table name or column.

Postgres a timestamp column constraint from NOT NULL to NULL

I'm trying to run a migration and make basically a column "modified" which is NOT NULL to be NULL. Like there is no need to have that constraint on it, I've run yoyo migrations and have the following output
psycopg2.ProgrammingError: syntax error at or near "timestamp"
LINE 1: ALTER TABLE shop ALTER COLUMN modified timestamp NULL
Pointing to the timestamp ^
the table itself looks
CREATE TABLE shop (
id SERIAL PRIMARY KEY,
uuid uuid NOT NULL UNIQUE,
created timestamp with time zone NOT NULL,
modified timestamp with time zone NOT NULL,
deleted timestamp with time zone
);
I've tried to search the web, and found a few similar articles on stackoverflow but it didn't help, so hopefully someone here can help.
Edit:
steps = [
step("""ALTER TABLE phrases
ALTER COLUMN modified TYPE timestamp,
ALTER column modified SET NULL
;""")
]
In yoyo migration
In Postgres, you can make a column nullable with DROP NOT NULL:
ALTER TABLE shop ALTER column modified DROP NOT NULL;
If you want to change the datatype at the same time, then:
ALTER TABLE shop
ALTER column modified DROP NOT NULL,
ALTER COLUMN modified TYPE timestamp
;
Demo on DB Fiddle

Validating json string using CHECK constraint in Postgres (sql)

I have a table with below schema :
CREATE TABLE tbl_name (
id bigserial primary key,
phone_info json
);
Sample json data for phone_info column is given below .
{
"STATUS":{"1010101010":"1","2020202020":"1"},
"1010101010":"OK",
"2020202020":"OK"
}
Now I need to add a check constraint on phone_info column so that all key for "STATUS" ie(1010101010,2020202020) should exist as a (key,value) pair of phone_info column where value would be "OK".
So above sample data would satisfy the check constraint as there are following key value pair exists in phone_info column.
"1010101010":"OK"
"2020202020,":"OK"
I have tried below solution but this has not worked because array_agg function is not supported with check constraints.
ALTER TABLE tbl_name
ADD CONSTRAINT validate_info CHECK ('OK' = ALL(array_agg(phone_info->json_object_keys(phone_info->'STATUS'))) );
Can someone please help me out , Can I write a SQL function and use the function in check constraint?
With something like this I think you'll want an SQL function.
CREATE TABLE tjson AS SELECT '{
"STATUS":{"1010101010":"1","2020202020":"1"},
"1010101010":"OK",
"2020202020":"OK"
}'::json AS col;
perhaps something like:
CREATE OR REPLACE FUNCTION my_json_valid(json) RETURNS boolean AS $$
SELECT bool_and(coalesce($1->>k = 'OK','f'))
FROM json_object_keys($1->'STATUS') k;
$$ LANGUAGE sql IMMUTABLE;
... but remember that while PostgreSQL will let you modify that function, doing so can cause previously valid rows to become invalid in the table. Never modify this function without dropping the constraint then adding it back again.

Replace into equivalent for postgresql and then autoincrementing an int

Okay no seriously, if a PostgreSQL guru can help out I'm just getting started.
Basically what I want is a simple table like such:
CREATE TABLE schema.searches
(
search_id serial NOT NULL,
search_query character varying(255),
search_count integer DEFAULT 1,
CONSTRAINT pkey_search_id PRIMARY KEY (search_id)
)
WITH (
OIDS=FALSE
);
I need something like REPLACE INTO for MySQL. I don't know if I have to write my own procedure or something?
Basically:
check if the query already exists
if so, just add 1 to the count
it not, add it to the db
I can do this in my php code but I'd rather all that be done in postgres C engine
You have to add a unique constraint first.
ALTER TABLE schema.searches ADD UNIQUE (search_query);
The insert/replace command looks like this.
INSERT INTO schema.searches(search_query) VALUES ('a search query')
ON CONFLICT (search_query)
DO UPDATE SET search_count = schema.searches.search_count + 1;

Link a sequence with to an identity in hsqldb

In PostgreSql, one can define a sequence and use it as the primary key of a table. In HsqlDB, one can still accomplish creating an auto-increment identity column which doesn't link to any user defined sequence. Is it possible to use a user defined sequence as the generator of an auto-increment identity column in HsqlDB?
Sample sql in PostgreSql:
CREATE SEQUENCE seq_company_id START WITH 1;
CREATE TABLE company (
id bigint PRIMARY KEY DEFAULT nextval('seq_company_id'),
name varchar(128) NOT NULL CHECK (name <> '')
);
What's the equivalent in HsqlDB?
Thanks.
In version 2.0, there is no direct feature for this. You can define a BEFORE INSERT trigger on the table to do this:
CREATE TABLE company ( id bigint PRIMARY KEY, name varchar(128) NOT NULL CHECK (name <> '') );
CREATE TRIGGER trigg BEFORE INSERT
ON company REFERENCING NEW ROW AS newrow
FOR EACH ROW
SET newrow.id = NEXT VALUE FOR seq_company_id;
and insert without using any vlue for id
INSERT INTO company VALUES null, 'test'
Update for HSQLDB 2.1 and later: A feature has been added to support this.
CREATE SEQUENCE SEQU
CREATE TABLE company ( id bigint GENERATED BY DEFAULT AS SEQUENCE SEQU PRIMARY KEY, name varchar(128) NOT NULL CHECK (name <> '') );
See the Guide under CREATE TABLE http://hsqldb.org/doc/2.0/guide/databaseobjects-chapt.html#dbc_table_creation
In addition, 2.1 and later has a PostgreSQL compatibility mode in which it accepts the PostgreSQL CREATE TABLE statement that references the sequence in the DEFAULT clause and translates it to HSQLDB syntax.