2016-05-05 16 views
5

per quanto riguarda UPDATE multiple rows from multiple params in nodejs/pg, ho bisogno di eseguire il seguente:Converti oggetto array a matrice compatibile per nodejs/pg/unnest

update portfolios p 
set votes = s.votes 
from unnest(array[(5, 1), (15, 1), (25, 2)]) s (votes int, id int) 
where p.id = s.id 

dove la mia matrice in unnest è di $ 1, come segue:

update portfolios p 
set votes = s.votes 
from unnest($1) s (votes int, id int) 
where p.id = s.id 

Tuttavia, la mia serie in origine costituito da oggetti, come:

[{votes: 5, id: 1}, {votes: 15, id: 1}, {votes: 25, id: 2}] 

ho provato a convertirlo con:

my_array = my_array.map(function(e) { return tuple(e.votes, e.id); }); 

Ma questo fallisce.

Ho bisogno di correggere la matrice compatibile con i valori da utilizzare con pg e Client.query.

Come posso convertire il mio array di oggetti in modo che rispettino javascript e postgresql unnest?

+0

Perché è necessario eseguire questa singola istruzione 'update'? perché non eseguire più istruzioni 'update'? –

+0

Sto usando nodejs con pg che non supporta più query senza fare un ciclo manuale tra tutte le istruzioni - apparentemente. Se è disponibile un'altra soluzione, sono tutto orecchie. –

+0

Come fallisce? Esiste un modo per generare la query che viene inviata a Postgresql? –

risposta

0

Si potrebbe inviare la stringa JSON come è, e hanno PostgreSQL affare con esso:

update portfolios p 
set votes = s.votes 
from (
    select (e->>'votes')::int as votes, (e->>'id')::int as id 
    from (select (regexp_replace($1, '"\1"', 'g'))::jsonb as jarr) j 
    cross join jsonb_array_elements(jarr) e 
) s 
where p.id = s.id; 

Dove $1 è [{votes: 5, id: 1}, {votes: 15, id: 1}, {votes: 25, id: 2}]', '([a-z]+) come una stringa.

0

@Ziggy idea per passare JSON può funzionare anche se l'ideale sarebbe fare in modo che il driver adattare la matrice. Questa è la domanda finale il pilota deve passare a PostgreSQL

update portfolios p 
set votes = s.votes 
from (
    select (a->>'votes')::int as votes, (a->>'id')::int as id 
    from (
     select jsonb_array_elements(a) as a 
     from (values ('[{"votes": 5, "id": 1}, {"votes": 15, "id": 1}]'::jsonb)) s(a) 
    ) s 
) s 
where p.id = s.id 

e la query di passare al driver:

update portfolios p 
set votes = s.votes 
from (
    select (a->>'votes')::int as votes, (a->>'id')::int as id 
    from (
     select jsonb_array_elements(a) as a 
     from (values (($1)::jsonb)) s(a) 
    ) s 
) s 
where p.id = s.id 

Il parametro $1 deve essere jsonified con qualcosa come JSON.stringify:

var a = JSON.stringify(my_array_of_objects);