Używam SQLAlchemy i istnieją co najmniej trzy podmioty: engine
, session
i connection
, które mają execute
metody, więc jeśli na przykład chcemy, aby zaznaczyć wszystkie rekordy ze table
mogę to zrobić
engine.execute(select([table])).fetchall()
i to
connection.execute(select([table])).fetchall()
a nawet to
session.execute(select([table])).fetchall()
- wyniki będą takie same.
Jak rozumiem, jeśli ktoś engine.execute
go używa , tworzy connection
, otwiera session
(Alchemy zajmuje się tym za Ciebie) i wykonuje zapytanie. Ale czy istnieje globalna różnica między tymi trzema sposobami wykonywania takiego zadania?
Odpowiedzi:
Podsumowanie jednowierszowe:
Zachowanie
execute()
jest taka sama we wszystkich przypadkach, ale są 3 różne sposoby, wEngine
,Connection
iSession
zajęcia.Co to dokładnie jest
execute()
:Aby zrozumieć zachowanie
execute()
, musimy przyjrzeć sięExecutable
klasie.Executable
jest nadklasą dla wszystkich typów obiektów typu „instrukcja”, w tym select (), delete (), update (), insert (), text () - najprościej mówiąc,Executable
jest to konstrukcja wyrażenia SQL obsługiwana w SQLAlchemy.We wszystkich przypadkach
execute()
metoda przyjmuje tekst SQL lub skonstruowane wyrażenie SQL, tj. Dowolną z różnych konstrukcji wyrażeń SQL obsługiwanych w SQLAlchemy i zwraca wyniki zapytania (aResultProxy
- ZawijaDB-API
obiekt kursora, aby zapewnić łatwiejszy dostęp do kolumn wiersza).Aby wyjaśnić to dalej (tylko w celu wyjaśnienia pojęciowego, a nie zalecanego podejścia) :
Oprócz
Engine.execute()
(wykonywanie bezpołączeniowe),Connection.execute()
iSession.execute()
możliwe jest również użycieexecute()
bezpośrednio w dowolnejExecutable
konstrukcji.Executable
Klasa ma własną realizacjęexecute()
- zgodnie z oficjalnej dokumentacji, jedna linia tekstu o tym, coexecute()
robi, jest „ skompilować i wykonać toExecutable
”. W tym przypadku musimy jawnie powiązaćExecutable
(konstrukcję wyrażenia SQL) zConnection
obiektem lubEngine
obiektem (który niejawnie pobieraConnection
obiekt), abyexecute()
wiedział, gdzie wykonaćSQL
.Poniższy przykład dobrze to ilustruje - biorąc pod uwagę tabelę jak poniżej:
Jawne wykonanie czyli
Connection.execute()
przekazanie tekstu SQL lub skonstruowanego wyrażenia SQL doexecute()
metodyConnection
:Jawne wykonanie bezpołączeniowe tj.
Engine.execute()
- przekazanie tekstu SQL lub skonstruowanego wyrażenia SQL bezpośrednio doexecute()
metody Engine:Niejawne wykonanie, tj.
Executable.execute()
- jest również bezpołączeniowe i wywołujeexecute()
metodęExecutable
, to znaczy wywołujeexecute()
metodę bezpośrednio na samejSQL
konstrukcji wyrażenia (jej instancjiExecutable
).Uwaga: w celu wyjaśnienia podano domyślny przykład wykonania - ten sposób wykonania nie jest zdecydowanie zalecany - zgodnie z dokumentami :
Twoje pytania:
Masz rację co do części "jeśli ktoś
engine.execute
jej użyje , tworzyconnection
" ale nie dla "otwierasession
(alchemia dba o to za ciebie) i wykonuje zapytanie" - UżywanieEngine.execute()
iConnection.execute()
jest (prawie) tym samym, formalnieConnection
obiekt jest tworzony niejawnie , aw późniejszym przypadku jawnie tworzymy instancję. To, co naprawdę dzieje się w tym przypadku, to:W warstwie DB jest dokładnie to samo, wszystkie wykonują SQL (wyrażenie tekstowe lub różne konstrukcje wyrażeń SQL). Z punktu widzenia aplikacji są dwie możliwości:
Engine.execute()
lubConnection.execute()
sessions
- sprawnie obsługuje transakcję jako pojedyncza jednostka-of-pracy, z łatwością za pomocąsession.add()
,session.rollback()
,session.commit()
,session.close()
. Jest to sposób na interakcję z bazą danych w przypadku ORM, czyli mapowanych tabel. Zapewnia identity_map do natychmiastowego uzyskiwania dostępu do już używanych lub nowo utworzonych / dodanych obiektów podczas pojedynczego żądania.Session.execute()
ostatecznie używaConnection.execute()
metody wykonania instrukcji w celu wykonania instrukcji SQL. Korzystanie zSession
obiektu jest zalecanym sposobem SQLAlchemy ORM dla aplikacji do interakcji z bazą danych.Fragment dokumentacji :
źródło
Odpowiedź Nabeela obejmuje wiele szczegółów i jest pomocna, ale jej śledzenie było dla mnie niejasne. Ponieważ jest to obecnie pierwszy wynik Google dotyczący tego problemu, dodam moje zrozumienie dla przyszłych osób, które znajdą to pytanie:
Uruchamianie .execute ()
Ponieważ zarówno OP, jak i Nabell Ahmed zauważają, podczas wykonywania zwykłego wyniku
SELECT * FROM tablename
nie ma różnicy w podanym wyniku.Różnice między tymi trzema obiektami stają się ważne, w zależności od kontekstu, że
SELECT
oświadczenie jest stosowany lub, częściej, gdy chcesz robić inne rzeczy, jakINSERT
,DELETE
itpKiedy ogólnie używać silnika, połączenia, sesji
Silnik to obiekt najniższego poziomu używany przez SQLAlchemy. To utrzymuje pulę połączeń dostępnych do wykorzystania, gdy aplikacja potrzebuje porozmawiać z bazy danych.
.execute()
to wygodna metoda, która najpierw wywołuje,conn = engine.connect(close_with_result=True)
a następnieconn.execute()
. Parametr close_with_result oznacza, że połączenie jest zamykane automatycznie. (Parafrazuję nieco kod źródłowy, ale zasadniczo prawda). edycja: Oto kod źródłowy pliku engine.executeMożesz użyć silnika do wykonania surowego kodu SQL.
Jest to omówione w dokumentacji w ramach podstawowego użycia .
Połączenie jest (jak widzieliśmy powyżej) tym, co faktycznie wykonuje zapytanie SQL. Powinieneś to zrobić zawsze, gdy chcesz mieć większą kontrolę nad atrybutami połączenia, kiedy zostanie ono zamknięte, itp. Na przykład bardzo ważnym tego przykładem jest Transakcja , która pozwala zdecydować, kiedy zatwierdzić zmiany w bazie danych. Podczas normalnego użytkowania zmiany są automatycznie zatwierdzane. Korzystając z transakcji, możesz (na przykład) uruchomić kilka różnych instrukcji SQL, a jeśli coś pójdzie nie tak z jedną z nich, możesz cofnąć wszystkie zmiany naraz.
Umożliwiłoby to cofnięcie obu zmian w przypadku niepowodzenia jednej z nich, na przykład w przypadku zapomnienia o utworzeniu tabeli datalogu.
Jeśli więc wykonujesz surowy kod SQL i potrzebujesz kontroli, użyj połączeń
Sesje są używane w aspekcie zarządzania relacjami z obiektami (ORM) w SQLAlchemy (w rzeczywistości można to zobaczyć na podstawie sposobu ich importowania:)
from sqlalchemy.orm import sessionmaker
. Korzystają z połączeń i transakcji pod maską, aby uruchamiać automatycznie generowane instrukcje SQL..execute()
to wygodna funkcja, która przechodzi do wszystkiego, do czego jest przypisana sesja (zwykle jest to silnik, ale może to być połączenie).Jeśli korzystasz z funkcji ORM, użyj sesji; jeśli wykonujesz tylko proste zapytania SQL, które nie są powiązane z obiektami, prawdopodobnie lepiej będzie używać połączeń bezpośrednio.
źródło
""
?my_session.connection()
. Dokumenty: docs.sqlalchemy.org/en/13/orm/… .Oto przykład uruchomienia DCL (Data Control Language), takiego jak GRANT
źródło