LINUX.ORG.RU

модификация sql запроса «на лету»

 


0

1

Собственно есть задача модифициривать sql запрос пользователя и уже его отдавать непосредственно в sql.

То есть пишет условный вася:

select * from test where name = «petya»;

А мне надо модифицировать такой запрос «на лету» в силу моего понимания прекрасного:

select * from test where name = «vasya»;

Реально это вообще?! Cмотреть лучше в сторону proxy?

Перемещено a1batross из general

  1. Парсишь SQL каким-нибудь парсером SQL.
  2. Пишешь обход полученного AST в соответствии с бизнес-логикой.
  3. Генерируешь по изменённоиу AST SQL-код.
  4. ???????
  5. PROFIT.
theNamelessOne ★★★★★ ()
Последнее исправление: theNamelessOne (всего исправлений: 1)

По представленному примеру такое ощущение, что ты хочешь чего-то нехорошего.

А если нет — я бы уточнил задачу. У тебя SQL прямо именно пользователи руками пишут, и там может быть именно ХЗ что? Так-то я SQL регулярками модифицировал, но SQLи там брались всё-таки из программы и были выдержаны более-менее в едином стиле, это всё упрощало.

hobbit ★★★★★ ()
Последнее исправление: hobbit (всего исправлений: 3)
Ответ на: комментарий от hobbit

ну что тут можно нехорошего сделать?

просто есть куча мусорных запросов(написанных с опечатками или неверными данными), а ответить на них надо. ИИ я обучил как надо такие запросы понимать и что отвечать, а теперь не понимаю как же сам запрос к базе перехватить, модифицировать и потом ответить

Bajenko ()
Последнее исправление: Bajenko (всего исправлений: 1)
Ответ на: комментарий от WitcherGeralt

Ну какой API? Есть только отмытое за кучу бабла говно.

Я же в стартпосте привел пример. Есть толпа пользователей они вбивают запросы в свою программу, программа ломится по сети в базу, нихрена не находит и посылает пользователя. Пользователи - представительницы VK-большинства с соответствующим уровнем убер-интеллекта. Менять программу или её пользователей не представляется возможным поэтому пошел по пути наименьшего сопротивления: проанализировав наиболее частые ошибки скорректировать их. Оказалось нетрудно: имена, объекты и тп. Понятно что нет имени ‘Васелий’ или ‘Васька’, зато есть ‘Василий’, понятно, что нет ‘прздник’, а есть переулок ‘праздник’, что сломался не ‘лфт’, а ‘лифт’ итп. ИИ легко справился с такими правками, осталось это применить и вот с этим возникли проблемы.

Bajenko ()
Ответ на: комментарий от Bajenko

Прикольно и радикально.

Я так и не понял, пишут ли пользователи запрос вручную, или просто набирают параметры, а запрос генерирует программа. Если всё же программа, то запросы, наверняка, однотипные, и я бы пошел по самому простому пути и правил запросы регулярками, как выше предложил @hobbit.

WitcherGeralt ★★ ()
Последнее исправление: WitcherGeralt (всего исправлений: 1)
Ответ на: комментарий от WitcherGeralt

пользователи набирают в программе, программа шлет запрос. Ерундовый вопрос по сути - я в прогу по-началу хотел просто справочники прикрутить, которые просто у пользователей все правили бы на месте, но всё оказалось плохо - поддержки нет, фирмы нет, кто писал не ясно, только оплаченный счет нашли на её заказ.

Дай мне, пожалуйста, пример таких регулярок.

Bajenko ()
Ответ на: комментарий от Bajenko
In [1]: import re

In [2]: re.sub?
"""
Signature: re.sub(pattern, repl, string, count=0, flags=0)
Docstring:
Return the string obtained by replacing the leftmost
non-overlapping occurrences of the pattern in string by the
replacement repl.  repl can be either a string or a callable;
if a string, backslash escapes in it are processed.  If it is
a callable, it's passed the Match object and must return
a replacement string to be used.
File:      /data/data/com.termux/files/usr/lib/python3.8/re.py
Type:      function
"""

In [3]: q = 'select * from test where name = "yasya";'

In [4]: e = r'name\s?=\s?"([^\"]+)"'

In [5]: def fix_name(m):
   ...:     name = m.group(1)
   ...:     if name == 'petya':
   ...:         return 'name="pyotr"'
   ...:     return m.group(0)
   ...:

In [6]: re.sub(e, fix_name, q)
Out[6]: 'select * from test where name = "yasya";'

In [7]: q = 'select * from test where name = "petya";'

In [8]: re.sub(e, fix_name, q)
Out[8]: 'select * from test where name="pyotr";'
WitcherGeralt ★★ ()

Иметь где-то в системе код, который меняет по-тихому sql - плохая идея. Когда что-то пойдёт не так, его будут сперва долго искать, а потом долго ругаться матом. И хорошо, если ты будешь где-нибудь далеко, в этот момент.

crutch_master ★★★★★ ()
Последнее исправление: crutch_master (всего исправлений: 1)

Реально это вообще?!

Реально. Приведённый пример вообще на представлениях элементарно делается. create view ... as select coalesce(nullif(name, 'petya'), 'vasya') from ...

Cмотреть лучше в сторону proxy?

«Как чего-то там не назови - …» (с)

anonymous ()
Ответ на: комментарий от Bajenko

Наверняка эта программа шлёт ограниченное количество запросов. Посмотри на них на все и напиши шаблоны на регулярках, типа /<where name=«(.*)»$/mi, в зависимости от ситуации и исходного форматирования, чтобы матчило только то, что нужно. Конкретных примеров нельзя привести, не зная набора этих запросов, и сложность регулярки будет зависеть от их вида. Если диалект известный, а запросы сложные, возможно проще на самом деле парсер вставить и матчить аст, а не текст.

anonymous ()

Это называется параметры запроса. Запрос отдельно, параметры - отдельно. По-хорошему запросы пишет программист, а пользователи вводят значения параметров в поля ввода. Давать юзерам возможность самим писать SQL - очень плохая идея, обязательно кто-то напишет «DROP TABLE».

anonymous ()