Я использую SQLAlchemy и есть, по крайней мере , три лица: engine
, session
и connection
, которые имеют execute
метод, поэтому , если я , например , хочу , чтобы выбрать все записи из table
я могу сделать это
engine.execute(select([table])).fetchall()
и это
connection.execute(select([table])).fetchall()
и даже это
session.execute(select([table])).fetchall()
- результаты будут такими же.
Насколько я понимаю, если кто-то engine.execute
его использует, он создает connection
, открывает session
(Алхимия заботится об этом за вас) и выполняет запрос. Но есть ли глобальная разница между этими тремя способами выполнения такой задачи?
Ответы:
Однострочный обзор:
Поведение
execute()
такое же во всех случаях, но они 3 различных методов, вEngine
,Connection
иSession
классы.Что именно
execute()
:Чтобы понять поведение,
execute()
нам нужно заглянуть вExecutable
класс.Executable
является суперклассом для всех типов объектов «операторов», включая select (), delete (), update (), insert (), text () - проще говоря, этоExecutable
конструкция выражения SQL, поддерживаемая в SQLAlchemy.Во всех случаях
execute()
метод принимает текст SQL или сконструированное выражение SQL, то есть любую из разнообразных конструкций выражения SQL, поддерживаемых в SQLAlchemy, и возвращает результаты запроса (aResultProxy
- ОборачиваетDB-API
объект курсора, чтобы обеспечить более легкий доступ к столбцам строк).Чтобы прояснить это дополнительно (только для концептуального пояснения, не рекомендуемый подход) :
В дополнение к
Engine.execute()
(выполнение без установления соединения),Connection.execute()
иSession.execute()
также можно использоватьexecute()
непосредственно в любойExecutable
конструкции. У этогоExecutable
класса есть собственная реализацияexecute()
- Согласно официальной документации, однострочное описание того, что онexecute()
делает, - это « Скомпилировать и выполнить этоExecutable
». В этом случае нам нужно явно привязатьExecutable
(конструкцию выражения SQL) кConnection
объекту илиEngine
объекту (который неявно получаетConnection
объект), чтобыexecute()
он знал, где выполнитьSQL
.Следующий пример хорошо демонстрирует это - учитывая таблицу, как показано ниже:
Явное выполнение, т.е.
Connection.execute()
передача текста SQL или построенного выражения SQLexecute()
методуConnection
:Явное выполнение без установления соединения, т.е.
Engine.execute()
передача текста SQL или сконструированного выражения SQL непосредственноexecute()
методу Engine:Неявное выполнение, то есть
Executable.execute()
- также без установления соединения и вызываетexecute()
метод объектаExecutable
, то есть вызываетexecute()
метод непосредственно для самойSQL
конструкции выражения (экземпляраExecutable
).Примечание: приведен пример неявного выполнения с целью пояснения - этот способ выполнения настоятельно не рекомендуется - согласно документации :
Ваши вопросы:
Вы правы в части «если кто-то использует
engine.execute
это создаетconnection
», но не «открывает»session
(Алхимия заботится об этом за вас) и выполняет запрос »- ИспользованиеEngine.execute()
иConnection.execute()
(почти) одно и то же, формальноConnection
объект создается неявно , а в более позднем случае мы явно создаем его экземпляр. Что действительно происходит в этом случае:На уровне БД это одно и то же, все они выполняют 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 для взаимодействия приложения с базой данных.Выдержка из документации :
источник
Ответ Набиль охватывает множество деталей и полезен, но мне было сложно следить за ним. Поскольку в настоящее время это первый результат Google по этой проблеме, добавляю свое понимание этого для будущих людей, которые найдут этот вопрос:
Запуск .execute ()
Как отмечают OP и Nabell Ahmed, при выполнении простого результата
SELECT * FROM tablename
нет никакой разницы в полученном результате.Различия между этими тремя объектами становятся важными в зависимости от контекста, в
SELECT
котором используется оператор, или, что более часто, когда вы хотите сделать другие вещи, напримерINSERT
,DELETE
и т. Д.Когда использовать Engine, Connection, Session в целом
Engine - это объект самого низкого уровня, используемый SQLAlchemy. Он поддерживает пул соединений, доступных для использования всякий раз, когда приложению необходимо взаимодействовать с базой данных.
.execute()
- это удобный метод, который сначала вызывает,conn = engine.connect(close_with_result=True)
а затемconn.execute()
. Параметр close_with_result означает, что соединение закрывается автоматически. (Я немного перефразирую исходный код, но по сути это правда). изменить: вот исходный код для engine.executeВы можете использовать движок для выполнения необработанного SQL.
Это описано в документации по базовому использованию .
Соединение (как мы видели выше) - это то, что на самом деле выполняет работу по выполнению SQL-запроса. Вы должны делать это всякий раз, когда вам нужен больший контроль над атрибутами соединения, когда оно закрывается и т. Д. Например, очень важным примером этого является транзакция , которая позволяет вам решать, когда фиксировать изменения в базе данных. При обычном использовании изменения фиксируются автоматически. Используя транзакции, вы можете (например) запустить несколько разных операторов SQL, и если что-то пойдет не так с одним из них, вы можете отменить все изменения сразу.
Это позволит вам отменить оба изменения в случае сбоя одного, например, если вы забыли создать таблицу журнала данных.
Поэтому, если вы выполняете необработанный код SQL и нуждаетесь в управлении, используйте соединения.
Сеансы используются для аспекта управления отношениями объектов (ORM) SQLAlchemy (на самом деле вы можете видеть это по тому, как они импортируются :)
from sqlalchemy.orm import sessionmaker
. Они используют внутренние соединения и транзакции для выполнения своих автоматически сгенерированных операторов SQL..execute()
- это вспомогательная функция, которая передает все, к чему привязан сеанс (обычно движок, но может быть и соединением).Если вы используете функциональность ORM, используйте session; если вы выполняете только прямые SQL-запросы, не привязанные к объектам, вам, вероятно, лучше использовать соединения напрямую.
источник
""
?my_session.connection()
. Документы: docs.sqlalchemy.org/en/13/orm/… .Вот пример запуска DCL (языка управления данными), такого как GRANT
источник