velreine / postgres-json-magic

Doing some fancy stuff with PostgreSQL's JSON methods.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

PostgreSQL JSON Magic.

Makes postgres serialize an example object graph, here the "root" object is user, and the related "groups" are a ManyToMany relationship. Instead of using JOINS Subqueries are leveraged to serialize nested objects.

DROP TABLE public.user_groups;
DROP TABLE public.users;
DROP TABLE public.groups;

-- Table: public.groups
CREATE TABLE public.groups
(
    id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    name character varying(255) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT groups_pkey PRIMARY KEY (id),
    CONSTRAINT uq_name UNIQUE (name)
);


-- Table: public.users

CREATE TABLE public.users
(
    id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    name character varying(64) COLLATE pg_catalog."default" NOT NULL,
    email character varying(255) COLLATE pg_catalog."default" NOT NULL,
    CONSTRAINT users_pkey PRIMARY KEY (id),
    CONSTRAINT uq_email UNIQUE (email)
);


-- Table: public.user_groups
CREATE TABLE public.user_groups
(
    user_id integer NOT NULL,
    group_id integer NOT NULL,
    CONSTRAINT user_groups_pkey PRIMARY KEY (user_id, group_id),
    CONSTRAINT group_fk FOREIGN KEY (group_id)
        REFERENCES public.groups (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION,
    CONSTRAINT user_fk FOREIGN KEY (user_id)
        REFERENCES public.users (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
);


--- INSERT GROUPS
INSERT INTO "groups" ("id", "name") VALUES (1, 'Default User Group');
INSERT INTO "groups" ("id", "name") VALUES (2, 'User Group A');
INSERT INTO "groups" ("id", "name") VALUES (3, 'User Group B');

--- INSERT USERS
INSERT INTO "users" ("id", "name", "email") VALUES (1, 'Nicky', 'nicky@example.com');
INSERT INTO "users" ("id", "name", "email") VALUES (2, 'Wendy', 'wendy@example.com');
INSERT INTO "users" ("id", "name", "email") VALUES (3, 'Line', 'line@example.com');
INSERT INTO "users" ("id", "name", "email") VALUES (4, 'Kaj', 'kaj@example.com');
INSERT INTO "users" ("id", "name", "email") VALUES (5, 'Erik', 'erik@example.com');
INSERT INTO "users" ("id", "name", "email") VALUES (6, 'Flemming', 'flemming@example.com');

--- INSERT MANY TO MANY RELATIONS BETWEEN USERS AND GROUPS
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (1, 1);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (2, 2);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (3, 2);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (4, 2);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (5, 3);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (6, 3);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (1, 2);
INSERT INTO "user_groups" ("user_id", "group_id") VALUES (1, 3);



-- Example with ManyToMany relation (Many Users Have Many Groups, and Many Groups Have Many Users)
SELECT row_to_json(t)
FROM	(
	SELECT u.* , 
	(
		SELECT array_to_json(array_agg(row_to_json(g)))
		FROM (
			SELECT id, name
			FROM groups
			WHERE id IN (SELECT group_id FROM user_groups WHERE user_id = u.id)
		) g
	) AS groups
	FROM users u
) t;
```sql

About

Doing some fancy stuff with PostgreSQL's JSON methods.