Параметризация строки в кавычках в SQL DBI Python

Я использую pg8000 подключиться к базе данных PostgreSQL через Python. Я хотел бы иметь возможность отправлять даты в качестве параметров через cursor.execute метод:

def info_by_month(cursor, year, month):
    query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', '%s-%s-01')
    """
    cursor.execute(query, (year, month))
    return cursor

Это вызовет ошибку: InterfaceError: '%s' not supported in a quoted string within the query string, Можно использовать форматирование строки Python, чтобы вставить туда дату. Использование мини-языка форматирования строк обеспечивает некоторую степень проверки данных для предотвращения атак с использованием SQL-инъекций, но все еще довольно уродливо.

def info_by_month(cursor, year, month):
    query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', '{:04}-{:02}-01')
    """.format(year, month)
    cursor.execute(query)
    return cursor

Как мне отправить строку в кавычках в cursor.execute метод?

2 ответа

Решение

Сделать format заранее, а затем передать полученную строку в execute, Таким образом вы избежите возможности внедрения SQL-кода, но при этом получите желаемое форматирование.

например, запрос становится:

query = """
    SELECT *
    FROM info
    WHERE date_trunc('month', info.created_at) =
          date_trunc('month', %s)"""

А потом format а также execute будет выглядеть так:

dateStr = "{:04}-{:02}-01".format(year, month)
cursor.execute(query, dateStr)

Я использую psycopg2, но похоже, что pg8000 придерживается того же стандарта DBI, поэтому я ожидаю, что это будет работать и в pg8000.

Это можно сделать с помощью конкатенации в ущерб удобочитаемости.

query = """
  SELECT *
  FROM info
  WHERE date_trunc('month', info.created_at) =
        date_trunc('month', %s || '-' || %s || '-01')
"""
cursor.execute(query, (year, month))
Другие вопросы по тегам