Python, параметры SQLAlchemy передаются в connection.execute

Я использую 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
<p →
__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

Учебник дает довольно хороший пример:

>>> 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, [email protected]',)]

Сначала возьмите строку 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(). Вы можете читать документацию для этой функции несколькими способами.