[英]psycopg2/SQLAlchemy: execute function with custom type array parameter
我有一个自定义的 postgres 类型,如下所示:
CREATE TYPE "Sensor".sensor_telemetry AS
(
sensorid character varying(50),
measurement character varying(20),
val numeric(7,3),
ts character varying(20)
);
我正在尝试执行对 postgres 函数的调用,该函数将这种类型的数组作为参数。
我用 SQLAlchemy 调用这个函数如下:
result = db.session.execute("""select "Sensor"."PersistTelemetryBatch"(:batch)""", batch)
batch
看起来像:
{
"batch" : [
{
"sensorID" : "phSensorA.haoshiAnalogPh",
"measurement" : "ph",
"value": 8.7,
"timestamp": "2019-12-06 18:32:36"
},
{
"sensorID" : "phSensorA.haoshiAnalogPh",
"measurement" : "ph",
"value": 8.8,
"timestamp": "2019-12-06 18:39:36"
}
]
}
运行此执行时,我遇到了此错误:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) can't adapt type 'dict'
我猜 psycopg2 抱怨自定义类型数组条目作为字典,因为我可以将字典作为参数提供给其他 pg 函数执行(但这些字典不包含在这种情况下的数组中)。 我对此是否正确?
我如何正确地将这些对象的数组传递给我的 pg 函数?
传递数据的一种直接方法是将字典列表转换为Python 中的元组列表,并让 psycopg2 处理使它们适应合适的 SQL 结构:
from operator import itemgetter
ig = itemgetter("sensorID", "measurement", "value", "timestamp")
batch = {"batch": list(map(ig, batch["batch"]))}
query = """
SELECT "Sensor"."PersistTelemetryBatch"(
CAST(:batch AS "Sensor".sensor_telemetry[]))
"""
result = db.session.execute(query, batch)
当您的数据是dict
列表时,另一个有趣的选择是使用json_populate_record()
或json_populate_recordset()
,但对于那些您必须修复键以匹配的选项:
import json
batch = [{"sensorid": r["sensorID"],
"measurement": r["measurement"],
"val": r["value"],
"ts": r["timestamp"]}
for r in batch["batch"]]
batch = {"batch": json.dumps(batch)}
query = """
SELECT "Sensor"."PersistTelemetryBatch"(ARRAY(
SELECT json_populate_recordset(
NULL::"Sensor".sensor_telemetry,
:batch)))
"""
result = db.session.execute(query, batch)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.