Estoy tratando de mapear los resultados de una consulta a JSON usando la row_to_json()
función que se agregó en PostgreSQL 9.2.
Tengo problemas para descubrir la mejor manera de representar filas unidas como objetos anidados (relaciones 1: 1)
Esto es lo que probé (código de configuración: tablas, datos de muestra, seguidos de consulta):
-- some test tables to start out with:
create table role_duties (
id serial primary key,
name varchar
);
create table user_roles (
id serial primary key,
name varchar,
description varchar,
duty_id int, foreign key (duty_id) references role_duties(id)
);
create table users (
id serial primary key,
name varchar,
email varchar,
user_role_id int, foreign key (user_role_id) references user_roles(id)
);
DO $$
DECLARE duty_id int;
DECLARE role_id int;
begin
insert into role_duties (name) values ('Script Execution') returning id into duty_id;
insert into user_roles (name, description, duty_id) values ('admin', 'Administrative duties in the system', duty_id) returning id into role_id;
insert into users (name, email, user_role_id) values ('Dan', 'someemail@gmail.com', role_id);
END$$;
La consulta en sí:
select row_to_json(row)
from (
select u.*, ROW(ur.*::user_roles, ROW(d.*::role_duties)) as user_role
from users u
inner join user_roles ur on ur.id = u.user_role_id
inner join role_duties d on d.id = ur.duty_id
) row;
Descubrí que si lo usaba ROW()
, podría separar los campos resultantes en un objeto secundario, pero parece limitado a un solo nivel. No puedo insertar más AS XXX
declaraciones, ya que creo que debería necesitar en este caso.
Se me otorgan nombres de columna, porque lanzo al tipo de registro apropiado, por ejemplo ::user_roles
, con , en el caso de los resultados de esa tabla.
Esto es lo que devuelve esa consulta:
{
"id":1,
"name":"Dan",
"email":"someemail@gmail.com",
"user_role_id":1,
"user_role":{
"f1":{
"id":1,
"name":"admin",
"description":"Administrative duties in the system",
"duty_id":1
},
"f2":{
"f1":{
"id":1,
"name":"Script Execution"
}
}
}
}
Lo que quiero hacer es generar JSON para uniones (nuevamente 1: 1 está bien) de una manera en la que pueda agregar uniones y representarlas como objetos secundarios de los padres a los que se unen, es decir, como se muestra a continuación:
{
"id":1,
"name":"Dan",
"email":"someemail@gmail.com",
"user_role_id":1,
"user_role":{
"id":1,
"name":"admin",
"description":"Administrative duties in the system",
"duty_id":1
"duty":{
"id":1,
"name":"Script Execution"
}
}
}
}
Se agradece cualquier ayuda. Gracias por leer.