阵列/ Jsonb更新字段:psycopg2.ProgrammingError

时间:2018-11-16 15:52:34

标签: django django-serializer

使用Django 2.1 / python 3.6,我正在更新现有模型上的字段。

该字段具有以下类型:

from django.contrib.postgres.fields import (
    ArrayField,
    JSONField
)
waypoints = ArrayField(
    JSONField(
        default=list,
        null=True,
        blank=True
    ),
    size=None,
    null=True,
    blank=True
)

该字段将以以下格式存储数据:

[
    {'lat': 63.123334, 'lon': 13.433918, 'date': '2018-08-23 11:00:00', 'direction': 123, 'rpm': 0},
    {'lat': 42.315119, 'lon': -3.213883, 'date': '2018-08-12 09:15:00', 'direction': 95.45, 'rpm': 3998},
    {'lat': 51.763023, 'lon': 7.376109, 'date': '2018-08-19 03:30:00', 'direction': 45.76, 'rpm': 7823}
]

我很清楚这不是一个好习惯,而且更好的方法是将外键与其他模型一起使用,但是我的双手被束缚住了。

我的代码是:

scheduler_response = {
    "result": {
        "time": 23,
        "total_consumption": 98117,
        "waypoints": [
            {
                "lat": 42.315119,
                "lon": -3.213883,
                "date": "2018-08-12 09:15:00",
                "direction": 95.45,
                "rpm": 3998,
                "cumulative_consumption": 0
            },
            {
                "lat": 51.763023,
                "lon": 7.376109,
                "date": "2018-08-19 03:30:00",
                "direction": 45.76,
                "rpm": 7823,
                "cumulative_consumption": 44298
            },
            {
                "lat": 63.123334,
                "lon": 13.433918,
                "date": "2018-08-23 11:00:00",
                "direction": 123,
                "rpm": 0,
                "cumulative_consumption": 98117
            }
        ]
    }
}
scheduler_waypoints = scheduler_response.get('result').get('waypoints')
job_updates = {}
job_updates['waypoints'] = scheduler_waypoints
print(type(job_updates['waypoints']))
job_updates['total_consumption'] = scheduler_response.get('total_consumption')
serialized_job = JobSerializer(active_job, data=job_updates, partial=True)

if serialized_job.is_valid():
    print('is_valid')
    print(serialized_job.validated_data)
    serialized_job.save()
    print('FINISHED')

我的终端输出如下:

<class 'list'>
is_valid
OrderedDict([('total_consumption', None), ('waypoints', [{'lat': 42.315119, 'lon': -3.213883, 'date': '2018-08-12 09:15:00', 'direction': 95.45, 'rpm': 3998}, {'lat': 51.763023, 'lon': 7.376109, 'date': '2018-08-19 03:30:00', 'direction': 45.76, 'rpm': 7823}, {'lat': 63.123334, 'lon': 13.433918, 'date': '2018-08-23 11:00:00', 'direction': 123, 'rpm': 0}])])

请注意,尽管序列化程序已经过验证,但无法保存序列化程序(未打印“完成”)。

我遇到了错误:

Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: column "waypoints" is of type jsonb[] but expression is of type text[]
LINE 1: ...d" = 1, "total_consumption" = NULL, "waypoints" = ARRAY['{"l...
                                                            ^
HINT:  You will need to rewrite or cast the expression.

这是为什么?我在做什么错(除了不使用外键和其他模型之外)?

1 个答案:

答案 0 :(得分:0)

对于其他想要犯下这种at亵行为的人,答案是在模型中使用JSONBField,而不是在列表字段中使用JSONField,这是我对模型所做的更改:

from django.contrib.postgres.fields.jsonb import JSONField as JSONBField
class Job(models.Model):
    waypoints = JSONBField(
        default=list,
        null=True,
        blank=True
    )

调用序列化程序的代码可以正常工作。