[Python] Psycopg2 e serializzazione delle SELECT in JSON

Alberto Granzotto agranzot a gmail.com
Gio 16 Ott 2014 16:55:33 CEST


Chiedo venia, avrei potuto risparmiarti una mail, non avevo capito il
funzionamento del GROUP BY nella query, ci sono arrivato dopo che GROUP BY
1, 2 è equivalente a GROUP BY u.id, u.name :)

Grazie per tutte le indicazioni, ora che mi hai mostrato che a) si può fare
b) come si fa ho tutte le informazioni necessarie per divertirmi!

Alberto

2014-10-16 16:32 GMT+02:00 Daniele Varrazzo <piro a develer.com>:

> On 2014-10-16 15:08, Alberto Granzotto wrote:
>
>> Ciao Daniele, grazie per la esaustiva risposta, mi sembra tutto chiaro a
>> parte una cosa ->
>>
>> 2014-10-16 15:47 GMT+02:00 Daniele Varrazzo <piro a develer.com>:
>>
>>  On 2014-10-16 13:59, Alberto Granzotto wrote:
>>> [...]l as (id integer, email text);
>>>
>>> e riscrivi la tua query in maniera da resitiuire un array di questi tipi:
>>> test=> select u.id, u.name, array_agg((e.id, e.email)::t_email) from
>>> users u join emails e on u.id = e.user_id group by 1,2;
>>>
>>>
>> C'è modo di evitare il group by? O devo prima estrarmi tutti gli id delle
>> email associate allo specifico user e poi usarle nel group by? Cosa
>> succede
>> se invece di estrarre un solo user volessi estrarre N user?
>>
>
> Il group by e' necessario per usare array_agg: se non lo usi hai i dati di
> ogni utente ripetuti se un utente ha piu' di una email (come nella tua
> query originale). Puoi usare una sottoquery che crea una mappa id_utente ->
> array di t_email e fare il join di questa con gli utenti, ma un group by
> (sebbene piu' efficiente) ci vuole sempre, es. nella sottoquery.
>
> In linea generale, psycopg ti restituira' un oggetto per ogni record che
> Postgres genera: i gradi di liberta' sono nel record generato da postgres
> (quindi e.g. usare group by, creare array, strutture, dizionari, ecc.
> usando i tipi di postgres in maniera un po' piu' avanzata) e nel
> configurare il mapping tra i record letti e gli oggetti python creati da
> psycopg (giocando con i typecaster). Se esci da questo framework (un record
> -> un oggetto) allora devi fare qualcosa a valle di psycopg, quindi ti
> ritrovi con i tipi di algoritmi ripetitivi per cui hai scritto la mail in
> primo momento: iterare sugli utenti, controllare se li avevi gia' letti,
> metterli in un dict con una lista di email vuote, aggiungere una email...
>
> Quindi, detto questo, come mai vuoi evitare il group by? Ti aspetti di
> leggere i dati da postgres in una maniera che non ho capito (nel qual caso
> fammi un esempio) oppure ti aspetti un comportamento di psycopg che esula
> dal restitiure un oggetto per ogni record?
>
> Estrarre N utenti si fa esattamente come sopra: la query restituisce un
> record per utente, ognuno con la lista delle sue email, e puoi iterare sul
> cursore in tutti i modi che psycopg offre (fetchmany(), fetchall(), for
> record in cur:...)
>
>     test=> insert into users (name) values ('daniele');
>     INSERT 0 1
>     test=> insert into emails (user_id, email) values (2, 'piro a officine
> ');
>     INSERT 0 1
>     test=> insert into emails (user_id, email) values (2, 'piro a develer');
>     INSERT 0 1
>
>     In [20]: dcur.execute("select u.id, u.name, array_agg((e.id,
> e.email)::t_email) as emails from users u join emails e on u.id =
> e.user_id group by 1,2")
>
>     In [21]: dcur.fetchall()
>     Out[21]:
>     [{'emails': [
>         {'email': 'alberto a example.org', 'id': 1},
>         {'email': 'alberto a lemonparty.org', 'id': 2}],
>       'id': 1,
>       'name': 'alberto'},
>      {'emails': [
>         {'email': 'piro a officine', 'id': 4},
>         {'email': 'piro a develer', 'id': 5}],
>       'id': 2,
>       'name': 'daniele'}]
>
>
>
> -- Daniele
> _______________________________________________
> Python mailing list
> Python a lists.python.it
> http://lists.python.it/mailman/listinfo/python
>
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20141016/0952d805/attachment.html>


Maggiori informazioni sulla lista Python