Однорядковий огляд:
Поведінка execute()таке ж у всіх випадках, але вони 3 різних методів, в Engine, Connectionі Sessionкласи.
Що саме таке execute():
Для розуміння поведінки execute()нам потрібно заглянути в Executableклас. Executable- це суперклас для всіх типів об'єктів "оператор", включаючи select (), delete (), update (), insert (), text () - найпростішими можливими словами, a Executable- це конструкція SQL-виразів, підтримувана в SQLAlchemy.
У всіх випадках execute()метод приймає текст SQL або побудований вираз SQL, тобто будь-яка з різноманітності конструкцій вираження SQL, що підтримуються в SQLAlchemy, і повертає результати запитів (a ResultProxy- Обертає об'єкт DB-APIкурсору для забезпечення більш легкого доступу до стовпців рядків.)
Для подальшого уточнення (лише для концептуальної роз'яснення, а не для рекомендованого підходу) :
На додаток до Engine.execute()(безз'єднаному виконанню), Connection.execute()і Session.execute(), також можна використовувати execute()безпосередньо на будь-якій Executableконструкції. ExecutableКлас має свою власну реалізацію execute()- по офіційній документації, один рядок опису про те , що execute()робить « Compile і виконати цеExecutable ». У цьому випадку нам потрібно явно зв’язати Executable(конструкцію вираження SQL) з Connectionоб'єктом або, Engineоб'єктом (який неявно отримує Connectionоб’єкт), тож execute()буде відомо, де його виконати SQL.
Наступний приклад це наочно демонструє - З огляду на таблицю, як показано нижче:
from sqlalchemy import MetaData, Table, Column, Integer
meta = MetaData()
users_table = Table('users', meta,
Column('id', Integer, primary_key=True),
Column('name', String(50)))
Явне виконання, тобто Connection.execute()передача тексту SQL або побудованого вираження SQL execute()методу Connection:
engine = create_engine('sqlite:///file.db')
connection = engine.connect()
result = connection.execute(users_table.select())
for row in result:
# ....
connection.close()
Явне виконання без підключення, тобто Engine.execute()передача тексту SQL або побудований вираз SQL безпосередньо execute()методу Engine:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
Неявне виконання, тобто Executable.execute()- також є беззв'язним і викликає execute()метод методу Executable, тобто викликає execute()метод безпосередньо на SQLконструкцію вираження (екземпляр Executable) самого себе.
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
Примітка: Наведений приклад неявного виконання з метою уточнення - такий спосіб виконання вкрай не рекомендується - згідно з документами :
"Неявне виконання" - це дуже стара модель використання, яка в більшості випадків є більш заплутаною, ніж корисною, і її використання не перешкоджає. Обидві моделі, схоже, заохочують надмірне використання доцільних "скорочень" в дизайні додатків, що призводить до проблем згодом.
Ваші запитання:
Як я розумію, якщо хтось використовує engine.execute, він створює з'єднання, відкриває сеанс (Алхімія піклується про вас) і виконує запит.
Ви маєте право на частину, "якщо хтось використовує engine.executeїї, створює connection", але не для "відкривається session(Алхімія про це піклується про вас) і виконує запит" - Використання Engine.execute()і Connection.execute()(майже) одне і те ж, формально Connectionоб'єкт створюється неявно , а в пізнішому випадку ми явно це інстанціюємо. Що насправді відбувається в цьому випадку:
`Engine` object (instantiated via `create_engine()`) -> `Connection` object (instantiated via `engine_instance.connect()`) -> `connection.execute({*SQL expression*})`
Але чи існує глобальна різниця між цими трьома способами виконання такого завдання?
У шарі DB це точно те саме, що всі вони виконують SQL (текстовий вираз або різні конструкції вираження SQL). З точки зору програми, є два варіанти:
- Пряме виконання - за допомогою
Engine.execute()абоConnection.execute()
- Використання
sessions- ефективно обробляє транзакції як єдиний блок-оф-роботи, з легкістю через session.add(), session.rollback(), session.commit(), session.close(). Це спосіб взаємодії з БД у випадку ORM, тобто відображених таблиць. Надає identity_map для миттєвого отримання вже доступних або новостворених / доданих об’єктів під час одного запиту.
Session.execute()врешті-решт використовує Connection.execute()метод виконання операторів для виконання оператора SQL. Використання Sessionоб'єкта є рекомендованим способом взаємодії програми з базою даних SQLAlchemy ORM.
Уривок із документів :
Важливо зазначити, що при використанні ORQ SQLAlchemy до цих об'єктів взагалі не можна отримати доступ; натомість об’єкт Session використовується як інтерфейс до бази даних. Однак для програм, побудованих на основі прямого використання текстових SQL-висловлювань та / або конструкцій вираження SQL без участі служб управління вищим рівнем ORM, двигун та з'єднання є королем (і королевою?) - читайте далі.