43

我正在使用 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)
4

1 回答 1

92

本教程为此提供了一个很好的示例:

>>> 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 注入攻击风险。

接下来,您可以使用已使用的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()函数参数的一种方式。您可以通过几种不同的方式阅读该函数的文档

于 2013-10-11T17:53:09.420 回答