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学习之pymysql和sqlalchemy

SQLAlchemy 核心连接上下文管理器

python+sqlalchemy 完成Oracle数据库读写操作

使用 pymssql 的 Python/Flask/sqlAlchemy 环境中的 Adaptive Server 连接失败错误