v0devil
v0devil

Reputation: 522

Dynamic field name in queryset annotation

I need to rename output field name with incoming variable value. There is a function:

def metric_data(request, test_id, metric):
    metric_name = metric
    data = ServerMonitoringData.objects. \
        filter(test_id=test_id). \
        annotate(timestamp=RawSQL("((data->>%s)::timestamp)", ('timestamp',))).\
        annotate(metric=RawSQL("((data->>%s)::numeric)", (metric,))). \
        values('timestamp', "metric")

So in this case no matter what value comes with the variable metric the output is looking like:

 {"timestamp": "0:31:02", "metric": "8.82414500398"}

I need to have an output with a key names equals to metric variable (if metric == 'CPU_iowait'):

{"timestamp": "0:31:02", "CPU_iowait": "8.82414500398"}

Tryed to use something like this:

    metric_name = metric
...
    annotate(metric_name=F('metric')).\
    values('timestamp', metric_name)

But it is trying to find 'CPU_iowait' column when exists 'metric_name'. So is there any way to pass field name as a variable ?

Upvotes: 2

Views: 2090

Answers (1)

jnns
jnns

Reputation: 5644

# use dict to map the metric's name to a RawSQL query 
# and pass it as keyword argument to `.annotate`.
metric_mapping = {
    metric: RawSQL("((data->>%s)::numeric)", (metric,))
}
queryset.annotate(**metric_mapping)

Upvotes: 3

Related Questions