Python、SQLAlchemy 在 connection.execute 中传递参数
Posted
技术标签:
【中文标题】Python、SQLAlchemy 在 connection.execute 中传递参数【英文标题】:Python, SQLAlchemy pass parameters in connection.execute 【发布时间】:2013-10-19 07:25:52 【问题描述】:我正在使用 SQLAlchemy connection.execute(sql) 将选择结果转换为地图数组。有以下代码
def __sql_to_data(sql):
result = []
connection = engine.connect()
try:
rows = connection.execute(sql)
for row in rows:
result_row =
for col in row.keys():
result_row[str(col)] = str(row[col])
result.append(result_row)
finally:
connection.close()
return result
例如
__sql_to_data(sql_get_scan_candidate)
为我提供了很好的数据结构(当然我将它用于小型数据集)。
但是为了向 sql 添加参数,我目前正在使用格式,例如
return __sql_to_data(sql_get_profile.format(user_id))
问题 如何修改程序以使之成为可能
return __sql_to_data(sql_get_profile,user_id)
【问题讨论】:
【参考方案1】:The tutorial 给出了一个很好的例子:
>>> from sqlalchemy.sql import text
>>> s = text(
... "SELECT users.fullname || ', ' || addresses.email_address AS title "
... "FROM users, addresses "
... "WHERE users.id = addresses.user_id "
... "AND users.name BETWEEN :x AND :y "
... "AND (addresses.email_address LIKE :e1 "
... "OR addresses.email_address LIKE :e2)")
SQL>>> conn.execute(s, x='m', y='z', e1='%@aol.com', e2='%@msn.com').fetchall()
[(u'Wendy Williams, wendy@aol.com',)]
首先,获取您的 SQL 字符串并将其传递给 sqalchemy.sql.text()。这不是必需的,但可能是个好主意...
text() 提供的相对于纯字符串的优势是后端中立的 支持绑定参数、每个语句的执行选项,以及 作为绑定参数和结果列类型的行为,允许 SQLAlchemy 类型构造在执行语句时发挥作用 这是字面上指定的。
请注意,即使您没有使用text()
,也绝不应该只使用sql.format(...)
。这会导致更大的SQL injection 攻击风险。
接下来,您可以使用您已经使用的execute() 函数的关键字参数来指定实际参数。
现在,在您的示例中,您有一个包装执行功能的函数。因此,如果您想将其用于多个查询,您需要使参数能够接收您的参数。你可以像字典一样简单地做到这一点:
def _sql_to_data(sql, values):
...
conn.execute(sql, values)
values
将是一本字典。然后您可以像这样使用您的函数...
sql = 'SELECT ...'
data = 'user_id' : 3
results = _sql_to_data(sql, data)
使用关键字作为参数只是为execute()
函数指定参数的一种方式。您可以通过几种不同的方式阅读 the documentation 以了解该功能。
【讨论】:
谢谢你,我的错,由于某种原因我无法在文档中找到这个。我唯一的一个借口 SQLAlchemy 文档有些支离破碎,强调 ORM。 还有一个问题 - fetchAll() 然后在结果数据结构中迭代与内存消耗方面的逐行关联如何? @Denis:我不确定你的意思。也许您应该创建另一个 *** 问题,并尝试更具体地说明您的问题。text
不允许您创建一个值列表,这是一个巨大的缺点,并且在我的许多情况下经常使它无法使用,从而使格式成为唯一真正的方法。
@stevenwade 格式从来都不是真正的方法,除非你的意思是格式化列表值所需的占位符,SQLAlchemy 甚至使用bindparam(..., expanding=True)
为你做这件事。另一方面,一些 DB-API 驱动程序开箱即用地使数组适应合适的 SQL。以上是关于Python、SQLAlchemy 在 connection.execute 中传递参数的主要内容,如果未能解决你的问题,请参考以下文章
基础入门_Python-模块和包.深入SQLAlchemy之事务回滚与反射还原对象?
python操作mysql(pymysql + sqlalchemy)
python+sqlalchemy 完成Oracle数据库读写操作
使用 pymssql 的 Python/Flask/sqlAlchemy 环境中的 Adaptive Server 连接失败错误