Python、SQLAlchemy在connection.execute中传递参数

Python、SQLAlchemy在connection.execute中传递参数,python,sql,sqlalchemy,parameter-passing,Python,Sql,Sqlalchemy,Parameter Passing,我正在使用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

我正在使用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添加参数,我目前使用的格式是

return __sql_to_data(sql_get_profile.format(user_id))
问题 如何修改程序以使以下内容成为可能

return __sql_to_data(sql_get_profile,user_id)
这是一个很好的例子:

>>> 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字符串并将其传递给。这不是必要的,但可能是个好主意

text()相对于纯字符串提供的优势是后端无关的 还支持绑定参数、每语句执行选项 作为绑定参数和结果列的键入行为,允许 SQLAlchemy类型构造在执行语句时发挥作用 这是逐字说明的

请注意,即使您没有使用
text()
,也不应该只使用
sql.format(…)
。这会导致更大的攻击风险

接下来,您可以使用已经使用过的函数的关键字参数来指定实际参数

现在,在您的示例中,有一个函数包装了执行功能。因此,如果要将其用于多个查询,则需要使参数能够接收参数。你可以做一个非常简单的字典:

def _sql_to_data(sql, values):
    ...
    conn.execute(sql, values)
将是一个字典。然后您可以像这样使用您的函数

sql = 'SELECT ...'
data = { 'user_id' : 3 }
results = _sql_to_data(sql, data)

使用关键字作为参数只是为
execute()
函数指定参数的一种方法。您可以通过几种不同的方式阅读该函数。

谢谢,我的错,由于某种原因,我无法在doc中找到该函数。我唯一的一个借口SQLAlchemy doc有些零碎,重点放在ORM上。还有一个问题——fetchAll()和结果数据结构中的分级在内存消耗方面与for row in row有关吗?@Denis:我不确定你的确切意思。也许您应该创建另一个StackOverflow问题,并尝试更具体地说明您所问的问题。
text
不允许您创建一个值列表,这是一个巨大的缺点,在我的许多情况下,它往往无法使用,使格式成为唯一的实际方式。@stevenwade格式从来都不是真正的方式,除非您的意思是格式化列表值所需的占位符,否则SQLAlchemy甚至可以使用。另一方面,一些DB-API驱动程序使现成的数组适应合适的SQL。
sql = 'SELECT ...'
data = { 'user_id' : 3 }
results = _sql_to_data(sql, data)