我尝试通过执行原始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
语法,但我想知道是否有一个优雅的解决方案来创建这样的语句。我知道我可以循环遍历dicts列表并附加查询,但这并不适合我。任何建议将不胜感激。
我正在考虑这样的事情:
['trunc({} * {}, {}) as {}'.format(
d['column'], d['factor'], d['trunc'], d['description']) for d in l
]
答案 0 :(得分:1)
如果您使用的是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},
]
)