Однострочный обзор:
Поведение execute()такое же во всех случаях, но они 3 различных методов, в Engine, Connectionи Sessionклассы.
Что именно execute():
Чтобы понять поведение, execute()нам нужно заглянуть в Executableкласс. Executableявляется суперклассом для всех типов объектов «операторов», включая select (), delete (), update (), insert (), text () - проще говоря, это Executableконструкция выражения SQL, поддерживаемая в SQLAlchemy.
Во всех случаях execute()метод принимает текст SQL или сконструированное выражение SQL, то есть любую из разнообразных конструкций выражения SQL, поддерживаемых в SQLAlchemy, и возвращает результаты запроса (a ResultProxy- Оборачивает DB-APIобъект курсора, чтобы обеспечить более легкий доступ к столбцам строк).
Чтобы прояснить это дополнительно (только для концептуального пояснения, не рекомендуемый подход) :
В дополнение к Engine.execute()(выполнение без установления соединения), Connection.execute()и Session.execute()также можно использовать execute()непосредственно в любой Executableконструкции. У этого Executableкласса есть собственная реализация execute()- Согласно официальной документации, однострочное описание того, что он execute()делает, - это « Скомпилировать и выполнить это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, он создает соединение, открывает сеанс (Alchemy заботится об этом за вас) и выполняет запрос.
Вы правы в части «если кто-то использует 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*})`
Но есть ли глобальная разница между этими тремя способами выполнения такой задачи?
На уровне БД это одно и то же, все они выполняют 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 для взаимодействия приложения с базой данных.
Выдержка из документации :
Важно отметить, что при использовании ORM SQLAlchemy эти объекты обычно не доступны; вместо этого объект Session используется как интерфейс к базе данных. Однако для приложений, построенных на прямом использовании текстовых операторов SQL и / или конструкций выражений SQL без участия служб управления более высокого уровня ORM, Engine и Connection являются королем (и королевой?) - читайте дальше.