Python psycopg2/SQLAlchemy:使用自定义类型数组参数执行函数
我有一个自定义postgres类型,如下所示:Python psycopg2/SQLAlchemy:使用自定义类型数组参数执行函数,python,postgresql,sqlalchemy,psycopg2,Python,Postgresql,Sqlalchemy,Psycopg2,我有一个自定义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调用
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" : [
{
"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正在抱怨将自定义类型数组条目作为dict,因为我可以将字典作为参数提供给其他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)
将dicts转换为元组:使用链接答案psycopg/literal响应中的代码,元组列表看起来像['value'、'measurement'、'timestamp'、'sensorID'、'value'、'measurement'、'timestamp'、'sensorID']。我应该在这里提供这些键的值吗?此外,每个元组中值的顺序是否需要与我创建的pgsql类型相同@元组应该包含值,并且它们应该反映用户定义类型的字段顺序。仔细想想,这可能是Python的operator.itemgetter的一个很好的用例,如果给定多个键,iirc将返回值的元组。