11import math
22from uuid import UUID
3- from datetime import datetime
43from typing import Optional
5- from django .db .models import Min , Max , Count
4+ from django .db .models .functions import Coalesce
5+ from django .db .models import Min , Max , Count , Q , Value , OuterRef , Subquery
66from django .db .utils import IntegrityError , DatabaseError , DataError
7+ from django .contrib .postgres .aggregates import ArrayAgg
78from psycopg .errors import UniqueViolation
89from ninja .errors import HttpError
910from sta .models import Observation , Datastream
@@ -75,6 +76,27 @@ def get_observations(
7576 if order_rule ["field" ] not in ["Datastream/id" , "phenomenonTime" ]
7677 ]
7778
79+ result_qualifier_subquery = (
80+ Observation .result_qualifiers .through .objects .filter (
81+ ** {"observation" : OuterRef ("pk" )}
82+ )
83+ .values ("observation" )
84+ .annotate (
85+ codes = ArrayAgg (
86+ f"resultqualifier__code" ,
87+ distinct = True ,
88+ filter = ~ Q (** {"resultqualifier__code" : None }),
89+ )
90+ )
91+ .values ("codes" )[:1 ]
92+ )
93+
94+ observations = observations .annotate (
95+ result_qualifier_codes = Coalesce (
96+ Subquery (result_qualifier_subquery ), Value ([])
97+ )
98+ )
99+
78100 observations = self .apply_order (
79101 queryset = observations , component = ObservationSchema , order_by = ordering
80102 )
@@ -100,17 +122,6 @@ def get_observations(
100122 skip = pagination .get ("skip" ) if pagination else 0 ,
101123 )
102124
103- # result_qualifier_ids = list(set([rq_id for rq_ids in [
104- # observation.result_qualifiers for observation in observations if observation.result_qualifiers
105- # ] for rq_id in rq_ids]))
106- #
107- # result_qualifiers = ResultQualifier.objects.filter(id__in=result_qualifier_ids)
108- #
109- # result_qualifiers = {
110- # result_qualifier.id: result_qualifier
111- # for result_qualifier in result_qualifiers
112- # }
113-
114125 try :
115126 return {
116127 observation .id : {
@@ -123,16 +134,11 @@ def get_observations(
123134 else None
124135 ),
125136 "datastream_id" : observation .datastream_id ,
126- "result_quality" : None ,
127- # "result_quality": {
128- # "quality_code": observation.quality_code,
129- # "result_qualifiers": [
130- # {
131- # "code": result_qualifiers.get(result_qualifier).code,
132- # "description": result_qualifiers.get(result_qualifier).description
133- # } for result_qualifier in observation.result_qualifiers
134- # ] if observation.result_qualifiers is not None else []
135- # }
137+ "result_quality" : {
138+ "quality_code" : observation .quality_code ,
139+ "result_qualifiers" : observation .result_qualifier_codes
140+ if observation .result_qualifiers is not None else []
141+ }
136142 }
137143 for observation in observations
138144 }, count
0 commit comments