【问题标题】:Python, SQLAlchemy pass parameters in connection.executePython、SQLAlchemy 在 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)

【问题讨论】:

    标签: python sql sqlalchemy parameter-passing


    【解决方案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:我不确定你的意思。也许您应该创建另一个 StackOverflow 问题,并尝试更具体地说明您的问题。
    • text 不允许您创建一个值列表,这是一个巨大的缺点,并且在我的许多情况下经常使它无法使用,从而使格式成为唯一真正的方法。
    • @stevenwade 格式从来都不是真正的方法,除非你的意思是格式化列表值所需的占位符,SQLAlchemy 甚至使用bindparam(..., expanding=True) 为你做这件事。另一方面,一些 DB-API 驱动程序开箱即用地使数组适应合适的 SQL。
    猜你喜欢
    • 2019-06-07
    • 2020-10-21
    • 2021-11-22
    • 2017-12-23
    • 2016-02-08
    • 1970-01-01
    • 2016-10-23
    • 2015-03-16
    • 1970-01-01
    相关资源
    最近更新 更多