PostgreSQL中如何将SQL保留字作为变量写入SQL查询
在PostgreSQL中用Django处理SQL关键字作为变量的问题
你遇到的错误根源是:参数化查询的占位符%s仅用于传递数据值,不能替换SQL语法关键字。当你把"DESC"作为参数传入时,PostgreSQL会将其解析为字符串字面量,最终SQL变成ORDER BY nb 'DESC'——这会被数据库误认为是“把nb列转换为'DESC'类型”,而该类型不存在,因此抛出编程错误。
以下是两种可行的解决办法:
方法1:安全拼接SQL关键字(仅限固定可选值场景)
因为排序方向只有ASC和DESC两个合法选项,我们可以先校验输入的合法性,再直接拼入SQL,完全规避SQL注入风险。
修改你的query1函数:
def query1(choice, limit): # 先校验排序方向的合法性 if choice not in ("ASC", "DESC"): raise ValueError("排序方向只能是ASC或DESC") # 合法值直接拼入SQL return(f''' SELECT col1, SUM(col2) as nb FROM "Table" GROUP BY col1 ORDER BY nb {choice} LIMIT %s ''', [limit])
方法2:用Django ORM替代手写SQL(推荐)
Django的ORM可以自动处理SQL语法元素,无需手动拼接或参数化,既安全又符合框架规范。
示例代码:
from django.db.models import Sum def query1(choice, limit): # 校验排序方向合法性 if choice not in ("ASC", "DESC"): raise ValueError("排序方向只能是ASC或DESC") # 用ORM构建查询 queryset = ( Table.objects.values('col1') .annotate(nb=Sum('col2')) .order_by(f'nb__{choice.lower()}') # ORM支持用__asc/__desc后缀控制排序方向 [:int(limit)] # 对应SQL的LIMIT ) # 转换为和原函数一致的返回格式(嵌套元组的列表) return [(item['col1'], item['nb']) for item in queryset]
内容的提问来源于stack exchange,提问作者problème0123
相关产品推荐
相关产品推荐

