Invalid JSON text but it seems that it is okay [duplicate] - sql

This question already has answers here:
Do the JSON keys have to be surrounded by quotes?
(7 answers)
Closed 1 year ago.
I am using Sequeal Ace. It says this error
Invalid JSON text: "The document root must not be followed by other values." at position 6 in value for column 'orders.drink'.
CREATE TABLE `orders` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`user_id` int NOT NULL,
`drink` json NOT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
A json that I want to put in.
{"abc": {
"milk": 100,
"tea": 100
},
"def":{
"milk": 100,
"cola": 100,
}
}

Using your table I managed to do a simple insert with the following query. You need to just add quotation marks to the main keys in the object.
INSERT INTO orders (id, user_id, drink, meal) VALUES(2, 2, '{"yoji": {
"milk": 100,
"barley_tea": 100,
"soy_milk": 100
},
"nyuji":{
"milk": 100,
"barley_tea": 100,
"soy_milk": 100}
}', 'asd');

Related

How do we design schema for user settings table for postgresql?

How do we design schema for user settings/preferences table in a sql database like postgresql?
I am interested to know the proper way to design the schema of users_setting table where users are able to modify their settings. This seems to be a 1-to-1 relationship because each row of users table corresponds to a single row in the users_setting table
so this is like a 1-to-1 table relation between users and users_setting. Is this the wrong way to do this? I have searched online and could not really find any useful example schemas where users manage their settings. So here i am asking this question. I am certain this will help many people also
Here is what my current design looks like
DROP TABLE if exists users cascade;
DROP TABLE IF EXISTS "users";
DROP SEQUENCE IF EXISTS users_id_seq;
CREATE SEQUENCE users_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
CREATE TABLE "public"."users" (
"id" bigint DEFAULT nextval('users_id_seq') NOT NULL,
"email" text NOT NULL,
"password" text NOT NULL,
"full_name" text NOT NULL,
"status" text NOT NULL,
"is_verified" boolean NOT NULL,
"role" text NOT NULL,
"created_at" timestamptz NOT NULL,
"updated_at" timestamptz NOT NULL,
"verified_at" timestamptz NOT NULL,
CONSTRAINT "users_email_key" UNIQUE ("email"),
CONSTRAINT "users_pkey" PRIMARY KEY ("id")
) WITH (oids = false);
DROP TABLE if exists users_setting cascade;
DROP TABLE IF EXISTS "users_setting";
DROP SEQUENCE IF EXISTS users_setting_id_seq;
CREATE SEQUENCE users_setting_id_seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 CACHE 1;
CREATE TABLE "public"."users_setting" (
"id" bigint DEFAULT nextval('users_setting_id_seq') NOT NULL,
"default_currency" text NOT NULL,
"default_timezone" text NOT NULL,
"default_notification_method" text NOT NULL,
"default_source" text NOT NULL,
"default_cooldown" integer NOT NULL,
"updated_at" timestamptz NOT NULL,
"user_id" bigint,
CONSTRAINT "users_setting_pkey" PRIMARY KEY ("id")
) WITH (oids = false);
ALTER TABLE ONLY "public"."users_setting" ADD CONSTRAINT "users_setting_user_id_fkey" FOREIGN KEY (user_id) REFERENCES "users"(id) NOT DEFERRABLE;
begin transaction;
INSERT INTO "users" ("id", "email", "password", "full_name", "status", "is_verified", "role", "created_at", "updated_at", "verified_at") VALUES
(1, 'users1#email.com', 'password', 'users1', 'active', '1', 'superuser', '2022-07-05 01:05:50.22384+00', '0001-01-01 00:00:00+00', '2022-07-11 14:10:26.615722+00'),
(2, 'users2#email.com', 'password', 'users2', 'active', '0', 'user', '2022-07-05 01:05:50.22384+00', '0001-01-01 00:00:00+00', '2022-07-11 14:10:26.615722+00');
INSERT INTO "users_setting" ("id", "default_currency", "default_timezone", "default_notification_method", "default_source", "default_cooldown", "updated_at", "user_id") VALUES
(1, 'usd', 'utc', 'email', 'google', 300, '2022-07-13 01:05:50.22384+00', 2),
(2, 'usd', 'utc', 'sms', 'yahoo', 600, '2022-07-14 01:05:50.22384+00', 2);
commit;
so lets say i want to return a single row where a users.email is users1#email.com for example, here is query i can run
select * from users, users_setting where users.id = users_setting.user_id AND users.email = 'users1#email.com';
id email password full_name status is_verified role created_at updated_at verified_at id default_currency default_timezone default_notification_method default_source default_cooldown updated_at user_id
1 users1#email.com password users1 active 1 superuser 2022-07-05 01:05:50.22384+00 0001-01-01 00:00:00+00 2022-07-11 14:10:26.615722+00 1 usd utc email google 300 2022-07-13 01:05:50.22384+00 1
i can have a single table for this but the table will get really long row-wise as i add more and more thing. user settings is just one, there are other tables similar to this. So will be great to know how to design a situation like this properly
In your case a JSON could do the job:
ALTER TABLE public.users ADD user_settings jsonb NULL;
Update of settings will be something like:
UPDATE users
SET user_settings = '{"default_currency": "usd", "default_timezone" : "utc"}'
WHERE id = 1;
And select:
select * from users WHERE id = 1;
You will find:
Also consider in Postgresql you can index a JSON, for example to query on a particular setting. Se here: https://www.postgresql.org/docs/current/datatype-json.html#JSON-INDEXING
Specific:
Still, with appropriate use of expression indexes, the above query can
use an index. If querying for particular items within the "tags" key
is common, defining an index like this may be worthwhile:
CREATE INDEX idxgintags ON api USING GIN ((jdoc -> 'tags'));
With this solution you can avoid JSON. Drawback is that setting_value cannot be tailored to exact type you need, compared to your first idea.
For example you can create:
CREATE TABLE public.user_setting (
user_id bigint NOT NULL,
setting_name text NOT NULL,
setting_value text NULL,
CONSTRAINT user_setting_pk PRIMARY KEY (user_id,setting_name)
);
ALTER TABLE public.user_setting ADD CONSTRAINT user_setting_fk FOREIGN KEY (user_id) REFERENCES public.users(id);
At this point I suggest you to have 2 query, one for users and one for settings:
SELECT *
FROM user_setting us
where user_id = 1;

Postgres serial datatype for primary key returns null when sending json request from postman?

Stack: nodejs, expressjs, postgresql, postman for testing requests
My Postman request encounters an error that does not pass the JSON correctly. I get the error:
null value in column "productid" of relation "product" violates not-null constraint
Right now in the json body of my post request in postman:
{
"productID": "1",
"productName": "pH Cleanser",
"price": 25.0,
"quantity": 20
}
However I get an error: error: null value in column "productid" of relation "product" violates not-null constraint
detail: 'Failing row contains (null, pH Cleanser, 25, 20, 2022-01-12 14:34:48.604451, 2022-01-12 14:34:48.604451).',
hint: undefined,
position: undefined,
internalPosition: undefined,
internalQuery: undefined,
where: undefined,
schema: 'public',
table: 'product',
column: 'productid',
dataType: undefined,
constraint: undefined,
My table in SQL:
CREATE TABLE product
(
productID serial PRIMARY KEY,
productName VARCHAR (255) NOT NULL,
price FLOAT NOT NULL,
quantity INT NOT NULL,
createdAt timestamp DEFAULT CURRENT_TIMESTAMP,
updatedAt timestamp DEFAULT CURRENT_TIMESTAMP
);
What do I do with a serial data type when passing a JSON request? I thought I could put an integer manually but its invalid.
I can manually insert into the database from the terminal.
It looks like you are explicitly attempting to insert a null value into your primary key column. You should write the insert statement to either not include the productID column or to insert the postgres keyword DEFAULT. This will allow postgres to auto generate the id on insert. You can then retrieve the newly generated id from the postgres library you are using.

'{"queue":[],"recieved":[],"accepted":[]}' not a valid query [duplicate]

This question already has answers here:
How to include a PHP variable inside a MySQL statement
(5 answers)
Closed 2 years ago.
I'm receiving this error when trying to query a INSERT INTO request.
Table query:
CREATE TABLE `profiles` (
`userid` bigint(20) NOT NULL,
`balance` bigint(20) NOT NULL,
`respects` bigint(20) NOT NULL,
`tarowomaru` bigint(20) NOT NULL,
`taruwumaru` bigint(20) NOT NULL,
`suggestions` bigint(20) NOT NULL,
`friends` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`flags` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SQL query:
INSERT INTO profiles (userid, balance, respects, tarowomaru, taruwumaru, suggestions, friends, flags)VALUES (323470201016549378, 0, 0, 0, 0, 0, '{"queue":[],"recieved":[],"accepted":[]}', '[]')
Received error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '"queue":[],"recieved":[],"accepted":[]},[])' at line 17
Is there something wrong with {"queue":[],"recieved":[],"accepted":[]} or is there something wrong with my query? Is using get requests messing up the string?
I guess it was my query. My query before was
"INSERT INTO profiles (userid, balance, respects, tarowomaru, taruwumaru, suggestions, friends, flags) VALUES ($userid, $balance, $respects, $tarowomaru, $taruwumaru, $suggestions, $friends, $flags)"
so it wasn't sending {"queue":[],"recieved":[],"accepted":[]} as a string.
The fixed query:
"INSERT INTO profiles (userid, balance, respects, tarowomaru, taruwumaru, suggestions, friends, flags) VALUES ($userid, $balance, $respects, $tarowomaru, $taruwumaru, $suggestions, '$friends', '$flags')"
Thanks for you guy's help though!

How to search records using JSON function in mariadb from json array

I am learning JSON function in mariaDB where I have
CREATE TABLE IF NOT EXISTS products (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
type VARCHAR(1) NOT NULL,
name VARCHAR(40) NOT NULL,
format VARCHAR(20) NOT NULL,
price FLOAT(5, 2) NOT NULL,
attr JSON NOT NULL
);
INSERT INTO products (type, name, format, price, attr) VALUES
('M', 'Aliens', 'Blu-ray', 13.99,'{"video": {"resolution": "1080p", "aspectRatio": "1.85:1"}, "cuts": [{"name": "Theatrical", "runtime": 138}, {"name":"Special Edition", "runtime": 155}], "audio": ["DTS HD", "Dolby Surround"]}');
INSERT INTO products (type, name, format, price, attr) VALUES
('B', 'Foundation', 'Paperback', 7.99, '{"author": "Isaac Asimov", "page_count": 296}');
I want to find how many records are there where Cuts.name="Theatrical"
SELECT * FROM `products` WHERE JSON_VALUE(attr,'$.cuts.name')='Theatrical'
I am getting 0 results here. How to search data from json array ?
The square brackets [] should be used for arrays.
You can use JSON_EXTRACT(attr, "$.cuts[*].name") nested within JSON_CONTAINS() function with '"Theatrical"' argument to determine whether the tuples for name elements of cuts array contain '"Theatrical"' :
SELECT COUNT(*)
FROM `products`
WHERE JSON_CONTAINS( JSON_EXTRACT(attr, "$.cuts[*].name"), '"Theatrical"' )
Demo

postgres column "X" does not exist

I have this postgrse code:
CREATE TABLE IF NOT EXISTS config_change_log
(
id serial primary key,
last_config_version varchar(255) NOT NULL,
is_done Boolean NOT NULL DEFAULT '0',
change_description varchar(255),
timestamp timestamp default current_timestamp
);
INSERT INTO config_change_log(last_config_version, is_done, change_description )
VALUES("5837-2016-08-24_09-12-22", false, "{ 'key':'value'}");
and I get this error:
psql:createConfigChangeLog.sql:11: ERROR: column "5837-2016-08-24_09-12-22" does not exist
LINE 2: VALUES("5837-2016-08-24_09-12-22", false, "{ 'key':'value'}"...
how can it be? it's a value not a column.postgr
Use single quotes for string constants
INSERT INTO config_change_log(last_config_version, is_done, change_description )
VALUES('5837-2016-08-24_09-12-22', false, '{ ''key'':''value''}');
Also you can escape single quotes in data by doubling them
SQL FIDDLE DEMO