Однорядковий огляд:
Поведінка 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, двигун та з'єднання є королем (і королевою?) - читайте далі.