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 <p...@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 <p...@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@officine > '); > INSERT 0 1 > test=> insert into emails (user_id, email) values (2, 'piro@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': 'albe...@example.org', 'id': 1}, > {'email': 'albe...@lemonparty.org', 'id': 2}], > 'id': 1, > 'name': 'alberto'}, > {'emails': [ > {'email': 'piro@officine', 'id': 4}, > {'email': 'piro@develer', 'id': 5}], > 'id': 2, > 'name': 'daniele'}] > > > > -- Daniele > _______________________________________________ > Python mailing list > Python@lists.python.it > http://lists.python.it/mailman/listinfo/python >
_______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python