sessionmaker()
jest fabryką, ma zachęcić do umieszczania opcji konfiguracyjnych do tworzenia nowych Session
obiektów w jednym miejscu. Jest to opcjonalne, ponieważ możesz równie łatwo zadzwonić w Session(bind=engine, expire_on_commit=False)
dowolnym momencie, gdy potrzebujesz nowego Session
, z wyjątkiem tego, że jest on rozwlekły i zbędny, a ja chciałem powstrzymać rozprzestrzenianie się małych „pomocników”, z których każdy podchodził do problemu tej nadmiarowości w jakimś nowym i bardziej zagmatwany sposób.
sessionmaker()
Jest to więc tylko narzędzie, które pomaga tworzyć Session
obiekty, gdy ich potrzebujesz.
Następna część. Myślę, że pytanie brzmi, jaka jest różnica między robieniem nowego Session()
w różnych punktach a zwykłym używaniem go przez cały czas. Odpowiedź nie bardzo. Session
to pojemnik na wszystkie obiekty, które do niego włożysz, a następnie śledzi otwartą transakcję. W momencie wywołania rollback()
lub commit()
transakcja jest zakończona i Session
serwer nie ma połączenia z bazą danych, dopóki nie zostanie wezwany do ponownego wysłania kodu SQL. Łącza, które utrzymuje do mapowanych obiektów, mają słabe odwołania, pod warunkiem, że obiekty są Session
wolne od oczekujących zmian, więc nawet w tym względzie will opróżnia się z powrotem do zupełnie nowego stanu, gdy aplikacja utraci wszystkie odniesienia do zamapowanych obiektów. Jeśli zostawisz to z domyślną wartością"expire_on_commit"
ustawienie, wszystkie obiekty tracą ważność po zatwierdzeniu. Jeśli to się Session
zawiesi przez pięć lub dwadzieścia minut, a wszystkie rodzaje rzeczy zmieniły się w bazie danych następnym razem, gdy go użyjesz, załaduje cały nowy stan przy następnym dostępie do tych obiektów, nawet jeśli były one w pamięci przez dwadzieścia minut.
W aplikacjach internetowych zwykle mówimy: hej, dlaczego nie tworzysz zupełnie nowego Session
na każde żądanie, zamiast używać tego samego w kółko. Ta praktyka gwarantuje, że nowe żądanie rozpocznie się „po wyczyszczeniu”. Jeśli niektóre obiekty z poprzedniego żądania nie zostały jeszcze zebrane, a być może wyłączyłeś "expire_on_commit"
, być może jakiś stan z poprzedniego żądania nadal się kręci, a ten stan może być nawet dość stary. Jeśli uważasz, aby pozostawić expire_on_commit
włączone i zdecydowanie zadzwonić commit()
lub rollback()
po zakończeniu żądania, to w porządku, ale jeśli zaczniesz od zupełnie nowego Session
, nie ma nawet wątpliwości, że zaczynasz od czystego. Więc pomysł, aby każde żądanie rozpoczynać od nowegoSession
jest naprawdę najprostszym sposobem, aby upewnić się, że zaczynasz od nowa, i uczynić użycie expire_on_commit
praktycznie opcjonalnego, ponieważ ta flaga może spowodować dużo dodatkowego kodu SQL dla operacji, która wywołuje commit()
w środku serii operacji. Nie jestem pewien, czy to odpowiada na Twoje pytanie.
Następna runda dotyczy gwintowania. Jeśli Twoja aplikacja jest wielowątkowa, zalecamy upewnić się, że Session
używana jest lokalnie dla ... czegoś. scoped_session()
domyślnie ustawia go lokalnie dla bieżącego wątku. W aplikacji sieciowej, lokalne żądanie jest w rzeczywistości jeszcze lepsze. Flask-SQLAlchemy w rzeczywistości wysyła niestandardową „funkcję zakresu” do scoped_session()
, aby uzyskać sesję o zasięgu żądania. Przeciętna aplikacja Pyramid umieszcza sesję w rejestrze „żądań”. Korzystając z takich schematów, idea „utwórz nową sesję na początku żądania” nadal wygląda na najprostszy sposób na prostotę.