单行概览:
execute() 的行为在所有情况下都是相同的,但它们是 3 种不同的方法,分别在 Engine、Connection 和 Session 类中。
execute()到底是什么:
要了解execute() 的行为,我们需要查看Executable 类。 Executable 是所有“语句”类型对象的超类,包括 select()、delete()、update()、insert()、text() - 用最简单的话来说,Executable 是一个 SQL 表达式结构SQLAlchemy 支持。
在所有情况下,execute() 方法采用 SQL 文本或构造的 SQL 表达式,即 SQLAlchemy 支持的各种 SQL 表达式构造并返回查询结果(ResultProxy - 将 DB-API 游标对象包装到提供对行列的更轻松访问。)
进一步澄清(仅用于概念澄清,不是推荐的方法):
除了Engine.execute()(无连接执行)、Connection.execute() 和Session.execute(),还可以在任何Executable 构造上直接使用execute()。 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表达式传递给Connection的execute()方法:
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 表达式直接传递给 Engine 的 execute() 方法:
engine = create_engine('sqlite:///file.db')
result = engine.execute(users_table.select())
for row in result:
# ....
result.close()
隐式执行 即Executable.execute() - 也是无连接的,调用Executable的execute()方法,即直接在SQL表达式上调用execute()方法构造(Executable 的实例)本身。
engine = create_engine('sqlite:///file.db')
meta.bind = engine
result = users_table.select().execute()
for row in result:
# ....
result.close()
注意:出于澄清目的陈述了隐式执行示例 - 强烈不推荐这种执行方式 - 根据docs:
“隐式执行”是一种非常古老的使用模式,在大多数情况下是
比它有用的更令人困惑,因此不鼓励使用它。两个都
模式似乎鼓励过度使用权宜之计的“捷径”
应用程序设计会导致以后出现问题。
您的问题:
据我了解,如果有人使用 engine.execute 它会创建连接,
打开会话(Alchemy 为您关心它)并执行查询。
对于“如果有人使用engine.execute,它会创建connection”这部分是正确的,但对于“打开session(Alchemy 会为您关心它)并执行查询”这部分是正确的——使用Engine.execute() 和@ 987654370@ (几乎)是一回事,在形式上,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 推荐的应用程序与数据库交互的方式。
摘自docs:
需要注意的是,在使用 SQLAlchemy ORM 时,这些
对象通常不被访问;相反, Session 对象是
用作数据库的接口。但是,对于应用程序
围绕直接使用文本 SQL 语句和/或 SQL 构建
没有 ORM 更高层参与的表达式构建
管理服务,引擎和连接是国王(和女王?) -
继续阅读。