Zpět na domů

Filtry podle data v Apache Superset: obcházky

Článek analyzuje architektonická omezení filtrování podle data v Apache Superset (verze 3.x–6.x). Popisuje, proč volba default time column vychází z lexikografie, jaké rizika to vytváří v production a uvádí technicky odůvodněné obcházky pro middle/senior-vývojáře.

Superset a data: proč filtry lámejí business-logiku
Advertisement 728x90

Apache Superset: Jak obcházet omezení filtrů dle data ve verzích 3.x–6.x

Apache Superset neumožňuje přiřadit filtr dle data konkrétní časové sloupci na úrovni grafu — výběr je vždy globální pro celý dataset a určen lexikografickým pořadím názvů polí. To způsobuje kritické problémy v produkčních prostředích: nekontrolované změny business logiky, konflikty mezi dashboardy a skryté regrese při změně výchozího časového sloupce. V článku rozebíráme architektonické příčiny, ověřené praktické workarounds a technická omezení současných řešení.

Proč Superset vybírá bot_profile__updated — a proč je to nebezpečné

Superset automaticky nastavuje výchozí časový sloupec při vytvoření datasetu, přičemž se řídí pouze abecedním pořadím jmen sloupců typu TIMESTAMP, DATETIME nebo DATE. V datasetu messages je pole bot_profile__updated první v lexikografickém třídění mezi bot_profile__updated, ts, created_at a updated_at. Toto chování je definováno v souboru superset/datasets/models.py, kde metoda get_default_time_column() používá sorted([col for col in dataset.columns if col.is_temporal]) bez ohledu na semantiku, business kontext a metadata.

Klíčovým rizikem je, že změna výchozího časového sloupce v datasetu ovlivní všechny grafy a dashboardy, které ho využívají, i když logicky spadají do různých časových os. Například:

Google AdInline article slot
  • Graf „Aktivita botů“ by měl být filtrován podle ts (okamžik události);
  • Graf „Aktualizace profilu“ — podle bot_profile__updated (okamžik změny entity);
  • Oba využívají stejný dataset messages.

Pokud správce změní výchozí časový sloupec na ts, druhý graf začne zobrazovat data podle nesprávné časové osy — bez chyb, bez logů, bez varování. Žluté upozornění v UI to pouze připomíná, ale operaci neblokuje.

Time Column Filter: funkční kutilské řešení s systémovými limity

Od verze 3.0 zavedl Superset filtr typu Time Column, který zobrazuje rozbalovací seznam všech časových sloupců datasetu a umožňuje vybrat jeden. Jeho implementace však není řešením, ale abstrakcí nad existujícím defektem:

  • Hodnota vybraná v filtru Time Column Filter globálně přepisuje default_time_column pro všechny filtry dle data na daném dashboardu;
  • Nelze přidat dva nezávislé filtry dle data (například „období události“ a „období zpracování“) — oba budou používat jednu vybranou hodnotu;
  • Filtr nepodporuje podmíněné výrazy (WHERE ts BETWEEN ... AND ... AND updated_at > ...);
  • Neovlivňuje agregace v SQL dotazech, pouze filtraci prostřednictvím WHERE.

To vedlo k paternu „filtr-proxy“, kdy vývojáři musí duplikovat datasety s různými default_time_column, aby izolovali logiku. Takový přístup porušuje princip DRY, komplikuje udržování a zvyšuje zátěž metadata.

Google AdInline article slot

Praktická technická řešení pro middle/senior vývojáře

Pro stabilní provoz Supersetu v produkci se doporučují následující přístupy:

  • Vytvoření virtuálních datasetů prostřednictvím SQL Labu

- Pro každý unikátní časový kontext se vytvoří samostatný SQL dataset s explicitním SELECT ... AS time_dimension FROM ...;

- Jméno time_dimension se fixuje jako jediný časový sloupec, čímž se eliminuje nejednoznačnost;

Google AdInline article slot

- Příklad:

SELECT 
  ts AS time_dimension,
  user_id,
  event_type,
  payload
FROM messages
WHERE ts IS NOT NULL
  • Použití extra_json pro nutné přiřazení

- V editoru datasetu se do pole Extra JSON zadá:

{"default_time_column": "ts"}

- Toto funguje pouze při existenci odpovídajícího pole v columns.extra a vyžaduje ruční aktualizaci při změně schématu;

  • Patchování Dataset.get_default_time_column() v kustomním image

- Přidání podpory anotací prostřednictvím komentářů v DBMS (COMMENT ON COLUMN messages.ts IS 'time_dimension:primary');

- Parsení komentářů v get_default_time_column();

- Vyžaduje CI/CD integraci a testování kompatibility s novými verzemi.

  • Odpustění vestavěných filtrů v prospěchu parametrizovaných SQL grafů

- Všechny časové filtry se přenesou do WHERE podmínek grafu s použitím {{ filter_values('date_range') }};

- Umožňuje použít několik nezávislých filtrů a složité podmínky;

- Nevýhoda — ztrácí se vizualizace filtrů v UI dashboardu.

Co je důležité

  • Superset nerozlišuje semantičeské určení časových sloupců: ts, created_at, updated_at jsou zpracovávány jako rovnocenné řetězce pro třídění.
  • Změna default_time_column v datasetu není bezpečná operace: okamžitě ovlivní všechny závislé grafy bez zpětné vazby.
  • Time Column Filter není mechanismus připojení ke sloupci, ale globální přepínač času pro celý dashboard.
  • Verze 5.x a 6.x neodstraňují základní problém: logika výběru času zůstává v models.py, bez refaktoringu architektury filtrace.
  • Jediný spolehlivý způsob izolace je fyzické oddělení datasetů nebo přechod na parametrizované SQL vizualizace.

Ve Apache Supersetu zůstává filtrace dle data jednou z nejslabších stránek architektury. Absence podpory více časových os na úrovni datasetu, tvrdé připoutání k lexikografii jmen a absence mechanismu anotace sloupců znemožňují správné modelování eventových toků s několika časovými dimenzemi. To je obzvláště kritické pro analýzu IoT, finančních transakcí a logů mikroservisů, kde každá záznam obsahuje minimálně tři časové metky: event_time, ingestion_time, processing_time. Komunita navrhuje opravu prostřednictvím issue #32496, ale dosud neexistuje PR s implementací. Zatím je nejlepší praxe navrhovat datasety tak, aby v každém byl právě jeden smyslový časový sloupec, nebo se vyhnout vestavěným filtrům a raději používat kontrolovaná SQL řešení.

— Editorial Team

Advertisement 728x90

Číst dál