PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Ottieni un albero genitori + figli con pg-promise

Sono l'autore di pg-promise.

Quando hai 2 tabelle:Parent -> Child con relazione 1-a-molti e vuoi ottenere una matrice di Parent corrispondenti righe, ogni riga estesa con la proprietà children impostato su un array delle righe corrispondenti dalla tabella Child ...

Esistono diversi modi per ottenere questo risultato, poiché la combinazione di pg-promise e promesse in generale è molto flessibile. Ecco la versione più breve:

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 */
    });

Questo è ciò che facciamo lì:

Per prima cosa, chiediamo Parent elementi, quindi mappiamo ogni riga in una query per il corrispondente Child items, che poi imposta le sue righe nel Parent e lo restituisce. Quindi utilizziamo il metodo batch per risolvere l'array di Child query restituite dalla mappa del metodo.

AGGIORNAMENTO per ES7

È lo stesso di sopra, ma usando ES7 async /await sintassi:

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

L'attività verrà risolta con un array come questo:

[
    {
        "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"}
        ]
    }    
]

Riferimenti API:mappa, batch

AGGIORNAMENTO

Vedi una risposta migliore a questa:tabella JOIN come matrice di risultati con PostgreSQL/NodeJS.