2012-03-28 10 views
11

Potrzebuję odczytać dane ze wszystkich wierszy dużego stołu, ale nie chcę, aby pobrać wszystkie dane do pamięci w tym samym czasie. Czy istnieje funkcja SQLAlchemy obsługująca stronicowanie? Oznacza to, że przeciągnij kilka wierszy do pamięci, a następnie pobierz więcej, gdy zajdzie taka potrzeba.SQLAlchemy i stronicowania

Rozumiem, że możesz to zrobić z limit i offset jako this article sugeruje, ale wolałbym nie obsługiwać tego, jeśli nie muszę.

Odpowiedz

13

Zobacz this answer. W skrócie, możesz użyć operatora yield_per.

+0

Wygląda na to, że obsługuje paginację w kontekście renderowania strony internetowej ... Po prostu próbuję rozmawiać z bazą danych, bez nakładki. –

+0

W warstwie bazy danych iteracja "limit" i "offset" jest właściwie najbardziej odpowiednim scenariuszem, dokładnie tak, jak oryginalnie udokumentowano. Wierzę, że uzasadnieniem jest to, co dzieje się z bazą danych _anyway_, w związku z tym równie dobrze możesz podać własną pętlę 'for'. :) – MrGomez

+0

Właściwie, nie, bardzo się mylę. Aktualizuję moją odpowiedź, ponieważ znalazłem bardziej ostateczny zasób. – MrGomez

13

Jeśli używasz Flask-SqlAlchemy, zobacz metodę paginate z query. paginate oferuje kilka metod upraszczających paginację.

record_query = Record.query.paginate(page, per_page, False) 
total = record_query.total 
record_items = record_query.items 

Pierwsza strona powinna być 1 w przeciwnym razie wyjątek .total powraca podzielone przez zero

+0

Zignorujcie moje inne komentarze, działa to znakomicie, jak jest, właśnie robiłem 'dict (** request.args)' głupio w niezwiązanym obszarze i otrzymuję nieoczekiwane wyniki. – robru

+0

Nie może to być nadal zły pomysł, ponieważ sprawdzasz źródło, w którym używają limitu i przesunięcia. Teraz, jeśli wartość przesunięcia jest zbyt duża, to baza danych przejdzie przez wszystkie te wartości, powodując problem z wydajnością. –

0

Jeśli nie używasz kolbie można użyć „kawałek” sqlalchemy funkcji lub combo „limit” & „offsetu ", jak wspomniano here. Np .:

some_query = Query([TableBlaa]) 
query = some_query.limit(number_of_rows_per_page).offset(page_number*number_of_rows_per_page) 
# -- OR -- 
query = some_query.slice(page_number*number_of_rows_per_page, (page_number*number_of_rows_per_page)+number_of_rows_per_page) 
current_pages_rows = session.execute(query).fetchall() 
+0

Przesunięcie granicy jest złe, jeśli przesunięcie jest wysokie, ponieważ przeszło wszystkie poprzednie wiersze, aby pobrać wyrównane wiersze powodując problem z wydajnością –