Django使用django-postgres-extension操作ArrayField删除末尾元素及获取长度
问题1:删除数组最后一个元素的正确语法
你使用ArrayRemove报错的核心原因是该函数的作用是删除数组中所有和指定值相等的元素,不支持按索引删除元素。要实现截断末尾元素的需求,可以直接用数组切片实现:
from django.db.models import F # 移除数组最后一个元素 MyMeasData.objects.filter(ipAddress=ipa).update( paramOne=F('paramOne')[0:F('paramOne__len') - 1] )
如果你的需求是始终保留最新的n个样本,完全可以把追加和截断合并为一步操作,不需要先判断长度再执行删除,性能更高:
from django_postgres_extensions.models.functions import ArrayPrepend from django.db.models import F, Value # 示例n为你要保留的样本总数 n = 10 MyMeasData.objects.filter(ipAddress=ipa).update( paramOne=ArrayPrepend(Value(param1), F('paramOne'))[0:n] )
小提示:你原有代码中ArrayPrepend的第二个参数直接传字段名的写法可以运行,但更推荐用F('paramOne')显式标记为字段引用,避免大小写拼写错误的问题。
问题2:获取ArrayField的数组长度
不需要查询整个数组内容再计算长度,可以直接在数据库层面通过函数计算长度,性能更好:
from django.db.models.functions import Length # 直接返回paramOne的数组长度,为None表示数组为空 arr_len = MyMeasData.objects.filter(ipAddress=ipa).annotate( param_len=Length('paramOne') ).values_list('param_len', flat=True).first()
如果运行时出现Length函数不兼容ArrayField的问题,可以自定义函数调用PostgreSQL原生的array_length方法:
from django.db.models import Func, IntegerField class ArrayLength(Func): function = 'array_length' output_field = IntegerField() arr_len = MyMeasData.objects.filter(ipAddress=ipa).annotate( # 第二个参数1表示一维数组,固定传即可 param_len=ArrayLength('paramOne', 1) ).values_list('param_len', flat=True).first()
内容的提问来源于stack exchange,提问作者jgporko
相关产品推荐
相关产品推荐

