繁体   English   中英

Python Django从给定列表构建原始SQL查询

[英]Python Django Build Raw SQL Query From a Given List

我尝试通过执行原始SQL查询从数据库后端获取一些信息。 我需要进行计算(将一个字段乘以一个因子,然后将其截断),然后以高效的方式将其转换为JSON 这就是为什么我选择不在此处使用( Django )ORM的原因。

with connection.cursor() as cursor:
    cursor.execute(
      '''
      SELECT json_build_object(
        'data', array_agg(r)
      )
      FROM (
        SELECT
          time,
          trunc(column1 * 100, 2) as COL1,
          trunc(column2 * 100, 2) as COL2,
          [...]
        FROM measurements
          WHERE device_id=%s
          ORDER BY time DESC
          LIMIT 5
      ) r
      ''',
      [device_id]
  )
  result = cursor.fetchall()

我需要从以下列表中改写上面的语句:

[
  {'column': 'column1', 'factor': 100, 'description': 'COL1', 'trunc': 2},
  {'column': 'column2', 'factor': 100, 'description': 'COL2', 'trunc': 2},
  [..]
]

由于我还不习惯使用python语法,所以我想知道是否存在一种优雅的解决方案来创建这样的语句。 我知道我可以遍历字典列表并追加查询,但这对我来说并不好。 任何建议,将不胜感激。

我在想这样的事情:

['trunc({} * {}, {}) as {}'.format(
  d['column'], d['factor'], d['trunc'], d['description']) for d in l
]

如果您使用的是psycopg 2.7,则可以使用sql模块,这将确保一切安全

from psycopg2 import sql

query = sql.SQL('''
  SELECT json_build_object(
    'data', array_agg(r)
  )
  FROM (
    SELECT time, {}
    FROM measurements
      WHERE device_id=%s
      ORDER BY time DESC
      LIMIT 5
  ) r
''')

truncated_rows = sql.SQL(', ').join(
    sql.SQL('trunc({} * {}, {}) as {}').format(
        sql.Identifier(d['column']),
        sql.Literal(d['factor']),
        sql.Literal(d['trunc']),
        sql.Identifier(d['description'])
    )
    for d in l
)

with connection.cursor() as cursor:
    cursor.execute(query.format(truncated_rows), [device_id])

在2.6及更早版本中,您将不得不使用python字符串格式

','.join(
    'trunc({column} * {factor}, {trunc}) as {description}'.format(**data)
    for data in
    [
        {'column': 'column1', 'factor': 100, 'description': 'COL1', 'trunc': 2},
        {'column': 'column2', 'factor': 100, 'description': 'COL2', 'trunc': 2},
    ]
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM