PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Obtenha uma árvore de pais + filhos com pg-promise


Eu sou o autor de pg-promise.

Quando você tem 2 tabelas:Parent -> Child com relacionamento de 1 para muitos e você deseja obter uma matriz de correspondência Parent linhas, cada linha estendida com a propriedade children definido para uma matriz das linhas correspondentes da tabela Child ...

Existem várias maneiras de fazer isso, pois a combinação de pg-promise e promessas em geral é muito flexível. Aqui está a versão mais curta:
db.task(t => {
    return t.map('SELECT * FROM Parent WHERE prop1 = $1', [prop1], parent => {
        return t.any('SELECT * FROM Child WHERE parentId = $1', parent.id)
            .then(children => {
                parent.children = children;
                return parent;
            });
    }).then(a => t.batch(a))
})
    .then(data => {
        /* data = the complete tree */
    });

Isso é o que fazemos lá:

Primeiro, consultamos Parent itens, mapeamos cada linha em uma consulta para o Child correspondente items, que então define suas linhas no Parent e o devolve. Em seguida, usamos o método batch para resolver o array de Child consultas retornadas do mapa de métodos.

ATUALIZAÇÃO para ES7


Aqui está o mesmo que acima, mas usando ES7 async /await sintaxe:
await db.task(async t => {
    const parents = await t.any('SELECT * FROM Parent WHERE prop1 = $1', [prop1]);
    for(const p of parents) {
        p.children = await t.any('SELECT * FROM Child WHERE parentId = $1', [p.id]);
    }
    return parents;
});
// the task resolves with the correct data tree

A tarefa será resolvida com uma matriz como esta:
[
    {
        "parent1-prop1", "parent1-prop2",
        "children": [
            {"child1-prop1", "child1-prop2"},
            {"child2-prop1", "child2-prop2"}
        ]
    },
    {
        "parent2-prop1", "parent2-prop2",
        "children": [
            {"child3-prop1", "child3-prop2"},
            {"child4-prop1", "child4-prop2"}
        ]
    }    
]

Referências de API:mapa, lote

ATUALIZAÇÃO

Veja uma resposta melhor para isso:JOIN table como array de resultados com PostgreSQL/NodeJS.