【问题标题】:How to perform a parametrized raw query in Django?如何在 Django 中执行参数化原始查询?
【发布时间】:2021-08-30 20:56:11
【问题描述】:

我正在阅读官方Django documentation,但我找不到我的问题的答案。

现在我已经实现了这个查询,使用 Django 的自定义 MariaDB 连接器:

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

它可以工作,但现在我需要将此查询调整为 django 的默认 MySQL 后端。

我尝试过的:

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('%', ?, '%') 部分,我不知道如何将其转换为 Django 可以解释的内容。

有什么想法吗?

【问题讨论】:

  • 为什么使用原始查询而不是 ORM?
  • 我不允许在这个项目中使用 ORM。
  • 您的第一个查询可能需要进行一些调整:您需要将? 替换为%s 以传递参数,并且您需要将% 替换为%%,因为单个百分比是一个“转义”字符并包含一个文字 % 字符,您需要传递 %%It's in the docs - 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
  • @IainShelvington 现在一切正常,除了这部分:a.report_notation LIKE concat('%', ?, '%'),我不知道如何转换为 django 参数化查询。
  • 不会是a.report_notation LIKE concat('%%', %s, '%%')吗?

标签: mysql django mariadb


【解决方案1】:

您的第一个查询应该可以很好地调整以匹配 Django 期望的格式。

首先,将? 替换为%s 以将参数传递给查询

其次,将%替换为%%,因为单个百分比是“转义”字符,您需要转义转义字符

DOCS

这是您的原始查询被截断以显示其工作原理的示例

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-08
    • 2012-03-13
    • 1970-01-01
    • 2018-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-02
    • 1970-01-01
    相关资源
    最近更新 更多