# meteo/schema.py from __future__ import annotations from dataclasses import dataclass from typing import List from influxdb_client import InfluxDBClient @dataclass(frozen=True) class MeasurementField: """ Représente un champ (_field) d'un measurement InfluxDB. """ name: str type: str # "float", "string", "boolean", "integer", "unsigned" def list_measurements(client: InfluxDBClient, bucket: str) -> list[str]: """ Retourne la liste des measurements présents dans le bucket donné. Utilise le package Flux `schema.measurements`. """ query = f""" import "influxdata/influxdb/schema" schema.measurements(bucket: "{bucket}") """ query_api = client.query_api() tables = query_api.query(query) measurements: set[str] = set() for table in tables: for record in table.records: value = record.get_value() if isinstance(value, str): measurements.add(value) return sorted(measurements) def list_measurement_fields( client: InfluxDBClient, bucket: str, measurement: str, ) -> list[MeasurementField]: """ Retourne la liste des champs (_field) pour un measurement donné, avec leur type InfluxDB (float, string, boolean, integer, unsigned). Utilise le package Flux `schema.measurementFieldKeys`. """ query = f""" import "influxdata/influxdb/schema" schema.measurementFieldKeys( bucket: "{bucket}", measurement: "{measurement}", ) """ query_api = client.query_api() tables = query_api.query(query) fields: dict[str, str] = {} for table in tables: for record in table.records: name = record.get_value() type_str = str(record.values.get("type", "unknown")) if isinstance(name, str): fields[name] = type_str return [ MeasurementField(name=n, type=t) for n, t in sorted(fields.items(), key=lambda item: item[0]) ] def list_measurement_tag_keys( client: InfluxDBClient, bucket: str, measurement: str, ) -> list[str]: """ Retourne la liste des clés de tags (tag keys) pour un measurement donné. Utilise `schema.measurementTagKeys`. """ query = f""" import "influxdata/influxdb/schema" schema.measurementTagKeys( bucket: "{bucket}", measurement: "{measurement}", ) """ query_api = client.query_api() tables = query_api.query(query) keys: set[str] = set() for table in tables: for record in table.records: value = record.get_value() if isinstance(value, str): keys.add(value) return sorted(keys) def list_measurement_tag_values( client: InfluxDBClient, bucket: str, measurement: str, tag: str, ) -> list[str]: """ Retourne la liste des valeurs possibles pour un tag donné (par exemple `entity_id`) sur un measurement donné. Utilise `schema.measurementTagValues`. """ query = f""" import "influxdata/influxdb/schema" schema.measurementTagValues( bucket: "{bucket}", measurement: "{measurement}", tag: "{tag}", ) """ query_api = client.query_api() tables = query_api.query(query) values: set[str] = set() for table in tables: for record in table.records: value = record.get_value() if isinstance(value, str): values.add(value) return sorted(values)