Рубрики
Без рубрики

Функция Python для работы с динамическими запросами SQL

Привет, сообщество, я новичок здесь и хорошо, относительно новичок в разработке! Я стремлюсь быть полным стеком D … Tagged с Python, Postgres, SQL, WebDev.

Привет, сообщество, я новичок здесь и хорошо, относительно новичок в разработке! Я стремлюсь стать разработчиком полного стека однажды И я с нетерпением жду всего вдохновения, поддержки и руководства на этом пути.

Сегодня на работе я наткнулся на действительно интересное требование, которое, честно говоря, сначала было сложным, но для меня было скорее открытым глазами о моем самом Статический Подход к запросам SQL. В любое время, когда я должен был запросить базу данных, вот как я бы это сделал:

SELECT * FROM details WHERE firstName='John' AND lastName='Doe';

Я хочу означать, что я бы использовал статический запрос, потому что я всегда буду знать о параметрах (имена столбцов, Значения столбца и разные положения тоже! ) Но сегодня я должен был искать через таблицу, основанную исключительно на вводе пользователя, то есть поиск по конкретной таблице, не зная ничего о записях в этой таблице или поисково -запросе. Сначала сами понятие использования пользовательских входов в качестве параметров поиска сбило меня за собой. Я не знал о возможности работы с динамическими запросами SQL (эй, в моей защите, я просто разработчик бэкэнд-любителя), но, поскольку это было не подлежащим обсуждению, я решил сделать это.

Для этого конкретного проекта я работаю с:

  1. Django (Python Web Framework – Backend)
  2. PostgreSQL (RDBMS – База данных)
  3. React (библиотека JavaScript – Frontend)

Проект, над которым я работаю, довольно сложный, поэтому я постараюсь сохранить процесс поток настолько простым, насколько я могу, и сосредоточиться на фактической логике, чтобы решить проблему под рукой. Пользовательские входы фиксируются в видах вида с различными возможными именами поля для поиска вместе с окном поиска для каждого поля. Затем они отправляются на бэкэнд в качестве объекта запроса, когда пользователь достигает кнопки поиска следующим образом:

const res= await axios.get("http://127.0.0.1:8000/application/search/?query=" + JSON.stringify(queryObj));

Если вам любопытно узнать, как выглядит объект запроса, вот возможный пример поискового запроса, сгенерированный из входов- Имя: Иоанн Фамилия: DOE

let queryObj={firstName:"John", lastName:"Doe",};

В бэкэнд ( внутри приложения Django \ views.py ) QueryOBJ обрабатывается следующим образом:

from django.http import JsonResponse
import psycopg2
import ast
def search_table(request):
  search_query=request.GET.get('query')
  queryparam=ast.literal_eval(search_query)

На случай, если вам интересно, почему я использовал встроенную функцию ast.literal_eval (search_query) Здесь это потому, что search_query-это строковый объект, а не словарь Python из пар клавиш. Эта функция помогает преобразовать ключи объекта строки в search_query в реальные ключи словаря Python.

Двигаясь дальше, установив соединение с базой данных PostgreSQL с использованием PSYCOPG2:

from django.http import JsonResponse
import psycopg2
import ast
def search_table(request):
    search_query=request.GET.get('query')
    queryparam=ast.literal_eval(search_query)
    con=psycopg2.connect(database="database_name",user="user_name",password="pwd",host="0.0.0.0",port="12345")
    cursor=con.cursor()
    and_clause=[]
    for k,v in queryparam.items():
        and_clause.append("%s = '%s'" % (k,v))
    and_clause_str=' AND '.join(and_clause)
    sql_query='SELECT * FROM table_name WHERE ' + and_clause_str
    print(sql_query)
    cursor.execute(sql_query)
    result=cursor.fetchall()
    return JsonResponse(result)

Итак, код здесь довольно пояснительный, но просто для того, чтобы быстро провести вас через логику –

Я объявил список строк с именем and_clause который хранит Query_param Ключи словаря, которые будут использоваться в качестве названий столбцов и Query_param Словарь значения как фактическое значение, которое будет искать, разделенное = чтобы структурировать его как запрос SQL.

Если в Query_param Словарь, т. Е. Когда пользователь хочет искать на основе нескольких параметров или столбцов, я соединяю эти строки, используя «и» и храню ее в новой строковой переменной с именем and_clause_str Анкет

Вот как будет выглядеть окончательное заявление SQL:

  1. Функция прямо сейчас не генерирует полностью динамические запросы. Если бы вы заметили, я все еще указываю имя таблицы, а также имею обязательное место. У меня это специально по двум причинам:

    • Проект, над которым я работаю, стремится выполнить поисковые операции в базах данных, поэтому пункт «где» должен присутствовать, поскольку он действует как параметр поиска.
    • Имя таблицы в моем проекте будет очень стандартным и общим названием таблицы, которое будет поддерживаться как одно и то же имя в разных базах данных, поэтому у меня есть запрос с жестким именем таблицы.
  2. Насколько я понимаю в инъекциях SQL, все еще очень плохое, и я согласен, что этот код может быть подвержен инъекциям SQL, я планирую оптимизировать его дальше, чтобы предотвратить любую возможность быть подверженной таким атакам.

  3. Если вам интересно, что, если пользователь предоставил ввод, не является фактическим именем столбца в таблице, то я хотел бы сообщить вам, что поля столбца формы генерируются из бэкэнда и отправляются на бренд для включения поиска. Таким образом, в некотором смысле, только существующие имена столбцов заполнены.

Я надеюсь, что я отдал должное своему самым первым сообщениям в блоге! Я действительно надеюсь, что это окажется полезным или чем -то новым для всех, кто читает это. Я открыт для предложений по дальнейшему улучшению кода и хотел бы услышать ваши мысли или вопросы по динамическим запросам SQL.

Спасибо за чтение!

Оригинал: “https://dev.to/bhavanaeh/python-function-to-work-with-dynamic-sql-queries-25gk”