Как выполнить параметризованный необработанный запрос в Django?

#mysql #django #mariadb

Вопрос:

Я читаю официальную документацию Django, но не могу найти ответа на свой вопрос.

Прямо сейчас я реализовал этот запрос, работая с пользовательским соединителем MariaDB для Django:

 results = []
cursor  = get_cursor()
try:
    sql="SELECT a.*, COALESCE( NULLIF(a.aa, '.'), NULLIF(a.gen, '.') ) AS variant, b.*, c.* FROM `db-dummy`.sp_gen_data c JOIN `db-dummy`.gen_info a ON a.record_id = c.gen_id JOIN `db-dummy`.sp_data b ON b.record_id = c.sp_id WHERE a.gene_name LIKE concat(?, '%') AND a.report_notation LIKE concat('%', ?, '%') AND b.sp_id LIKE concat(?, '%');"
    data = (gen, var, sp)
    cursor.execute(sql, data)
except mariadb.Error as e:
    print(f"Error: {e}")
columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
    results.append(dict(zip(columns, row)))     
return results
 

Это работает, но теперь мне нужно адаптировать этот запрос к серверной части MySQL django по умолчанию.

Что я пробовал:

 results = []
cursor  = get_cursor()
sql="SELECT a.*, COALESCE( NULLIF(a.aa, '.'), NULLIF(a.gen, '.') ) AS variant, b.*, c.* FROM `db-dummy`.sp_gen_data c JOIN `db-dummy`.gen_info a ON a.record_id = c.gen_id JOIN `db-dummy`.sp_data b ON b.record_id = c.sp_id WHERE a.gene_name LIKE %s AND a.report_notation LIKE %s AND b.sp_id LIKE %s;"
data = ('{}%'.format(gen), '{}%'.format(var), '{}%'.format(sp))
cursor.execute(sql, data)

columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
    results.append(dict(zip(columns, row)))
return results
 

Так что в основном то, что я должен был изменить, чтобы это сработало, было LIKE concat(?, '%') для LIKE %s меня .

Проблема, со a.report_notation LIKE concat('%', ?, '%') своей стороны, в том, что я не знаю, как преобразовать его во что-то, что Джанго может интерпретировать.

Есть какие-нибудь идеи?

Комментарии:

1. Зачем использовать необработанный запрос, а не ORM?

2. Мне не разрешается использовать ORM в этом проекте.

3. Ваш первый запрос может работать с несколькими настройками: вам нужно заменить ? на %s для передачи параметров, и вам нужно заменить % на %% , так как один процент-это символ «escape», и чтобы включить буквальный % символ, который вам нужно передать %% . Это есть в документах Note that if you want to include literal percent signs in the query, you have to double them in the case you are passing parameters

4. @IainShelvington Сейчас все работает, за исключением этой части: a.report_notation LIKE concat('%', ?, '%') которую я не знаю, как преобразовать в параметризованный запрос django.

5. Разве это не так a.report_notation LIKE concat('%%', %s, '%%') ?

Ответ №1:

Ваш первый запрос должен быть в порядке, просто скорректирован в соответствии с форматом, который ожидает Django.

Во — первых, замените ? на %s для передачи параметров в запрос

Во-вторых, заменить % на %% как один процент-это символ «побег», и вам нужно избежать символа побега

Документы

Вот ваш исходный запрос, усеченный, чтобы показать пример того, как он может работать

 sql="... WHERE a.gene_name LIKE concat(%s, '%%') AND a.report_notation LIKE concat('%%', %s, '%%') AND b.sp_id LIKE concat(%s, '%%');"
data = (gen, var, sp)
cursor.execute(sql, data)