Ho appena aggiunto la funzionalità di prelettura che dovrebbe risolvere il tuo problema. Puoi prendere codice funzionante dal GitHub repository. Questa funzione farà parte della prossima versione Pony ORM 0.5.4.
Ora si può scrivere:
q = q.prefetch(Supplier)
o
q = q.prefetch(Order.supplier)
e Pony caricherà automaticamente connessi supplier
oggetti.
Qui di seguito mostrerò diverse query con il prefetching, utilizzando l'esempio standard di Pony con studenti, gruppi e reparti. Oggetti
from pony.orm.examples.presentation import *
Caricamento Student solo, senza precaricamento:
students = select(s for s in Student)[:]
Caricamento studenti insieme con i gruppi e dipartimenti:
students = select(s for s in Student).prefetch(Group, Department)[:]
for s in students: # no additional query to the DB is required
print s.name, s.group.major, s.group.dept.name
lo stesso come sopra, ma specificando gli attributi al posto di entità:
students = select(s for s in Student).prefetch(Student.group, Group.dept)[:]
for s in students: # no additional query to the DB is required
print s.name, s.group.major, s.group.dept.name
Caricamento studenti e suoi corsi (molti-a-molti):
students = select(s for s in Student).prefetch(Student.courses)
for s in students:
print s.name
for c in s.courses: # no additional query to the DB is required
print c.name
Come un parametri del metodo prefetch()
è possibile specificare entità e/o attributi. Se hai specificato un'entità, allora tutti gli attributi a con questo tipo verranno precaricati. Se hai specificato un attributo, allora questo attributo specifico sarà precaricato. Gli attributi to-many vengono precaricati solo se specificati esplicitamente (come nell'esempio Student.courses
). Il prefetching va in modo ricorsivo, quindi puoi caricare una lunga catena di attributi, come ad esempio student.group.dept
.
Quando l'oggetto è precaricato, per impostazione predefinita vengono caricati tutti gli attributi, ad eccezione degli attributi pigri e di molti attributi. È possibile precaricare esplicitamente gli attributi lazy e to-many se necessario.
Spero che questo nuovo metodo copra completamente il vostro caso d'uso. Se qualcosa non funziona come previsto, per favore start new issue on GitHub. Inoltre puoi discutere delle funzionalità e fare richieste di funzionalità allo Pony ORM mailing list.
P.S. Non sono sicuro che il pattern di repository che usi offra i tuoi seri benefici. Penso che in realtà aumenti l'accoppiamento tra il rendering del modello e l'implementazione del repository, perché potrebbe essere necessario modificare l'implementazione del repository (ad esempio aggiungere nuove entità all'elenco di precaricamento) quando il codice del modello inizia a utilizzare nuovi attributi. Con il decoratore di livello superiore @db_session
è sufficiente inviare il risultato della query al modello e tutto avviene automaticamente, senza necessità di preconfigurazione esplicita. Ma forse mi manca qualcosa, quindi sarò interessato a vedere ulteriori commenti sui vantaggi dell'uso del pattern di repository nel tuo caso.
Nel mio caso, il metodo decorato con 'db_session' si trova in un modulo di repository e avere un decoratore' db_session' al di fuori di questo repository annulla il suo scopo (aumentando l'accoppiamento tra la funzione route e l'implementazione del repository). C'è un modo più elegante di iterare attraverso tutti gli oggetti di ritorno di quello che ho tentato di fare? Vorrei che tutti i dati di tutti gli oggetti secondari disponibili uno il metodo restituisca il risultato. – kasperhj
@lejon Ho appena aggiornato la risposta –
Che suona alla grande! Nel frattempo intendo "toccare" dove necessario. Sono stato indotto in errore dal '[:]' come pensavo avrebbe congelato tutto nella query in una lista. – kasperhj