Integrationen¶
Die richtige Verbindungsart wählen¶
| Client-Typ | Empfohlene Methode | Warum |
|---|---|---|
| BI-Tools (Tableau, Power BI, Looker) | JDBC | Spaltenbasiertes Arrow-Flight-Streaming über die Leitung; BI-Tools haben einen integrierten JDBC-Assistenten und profitieren von der spaltenbasierten Zustellung mit hohem Durchsatz für große Ergebnismengen |
| psql, DBeaver, jedes PG-kompatible Tool | pgwire (nativer PG-Treiber) | Reibungslose Standardoption — kein spezieller Treiber erforderlich; nutzen Sie, was Sie bereits haben |
| Python-Datenstack (pandas, pyarrow) | provisa-client oder rohes ADBC |
Arrow-Batches im Streaming; kein Overhead durch Zeilenserialisierung |
| Spark, DuckDB, Pipelines mit hohem Durchsatz | Arrow Flight (ADBC) | Unbegrenztes spaltenbasiertes Streaming direkt in den Arrow-Speicher |
| Service-zu-Service (typisierte Verträge) | Protobuf gRPC | Pro Rolle generiertes Proto; Zeilen im Streaming; Typsicherheit |
| Webanwendungen, Skripting | HTTP (/data/graphql, /data/sql) |
Kein Treiber; Standard-HTTP; volle Auswahl an Abfragesprachen |
| REST-Clients (JSON:API-Standard) | GET /data/jsonapi/{table} |
JSON:API-v1.0-Umschlag; partielle Feldmengen, Paginierung, Filterung über Query-Parameter; kein Treiber |
pgwire — Nativer PostgreSQL-Treiber¶
Provisa implementiert das PostgreSQL-Drahtprotokoll (Protokollversion 3.0). Jeder Client, der PostgreSQL spricht, verbindet sich ohne speziellen Treiber.
Aktivieren Sie es, indem Sie PROVISA_PGWIRE_PORT (z. B. 5433) vor dem Start von Provisa setzen. Deaktiviert, wenn nicht gesetzt oder 0.
Warum pgwire statt JDBC?¶
Der JDBC-Treiber nutzt Arrow Flight als Transport und erfordert die Bereitstellung von provisa-jdbc.jar. pgwire erfordert nichts — wenn Sie bereits psql, DBeaver, SQLAlchemy oder einen PG-JDBC-Treiber haben, sind Sie fertig. Es ist die Variante mit dem geringsten Aufwand für reine SQL-Workloads.
JDBC ist die richtige Wahl für BI-Tools mit integriertem JDBC-Verbindungsassistenten, die vom spaltenbasierten Streaming von Arrow Flight für große Ergebnismengen profitieren. pgwire akzeptiert freies SQL gegen das vollständig veröffentlichte Schema — dieselben Abfragen, geringere Einrichtungskosten.
psql¶
DBeaver¶
- Neue Verbindung → PostgreSQL
- Host:
localhost, Port:5433 - Benutzername / Passwort wie in Provisa konfiguriert
- Kein zusätzlicher Treiber-Download erforderlich
SQLAlchemy (Python)¶
from sqlalchemy import create_engine
engine = create_engine("postgresql+psycopg2://alice:secret@localhost:5433/provisa")
df = pd.read_sql("SELECT * FROM sales.orders", engine)
Oder mit asyncpg:
Authentifizierung¶
Das Feld password des Startup-Pakets trägt die Anmeldedaten, und was die Anmeldedaten sind, wählt die Methode: ein persönliches Zugriffstoken, ein OIDC-Bearer-Token oder ein Passwort gegen den konfigurierten Provider. Unter dem Provider basic mit auth.scram: true wird das Passwort per SCRAM-SHA-256 bewiesen statt gesendet. Client-Zertifikate werden unterstützt. Im Trust-Modus (none) wird der Benutzername direkt einer Rolle zugeordnet und das Passwort ignoriert.
Die vollständige Tabelle Schnittstelle × Methode steht im Sicherheitsmodell. MD5 wird nicht unterstützt; aktivieren Sie TLS (PROVISA_PGWIRE_CERT / PROVISA_PGWIRE_KEY), wenn Sie in einem nicht vertrauenswürdigen Netzwerk arbeiten.
Einschränkungen¶
- Nur SQL. GraphQL und Cypher werden über pgwire nicht akzeptiert.
- Nicht schreibgeschützt.
COPY ... FROM STDINfügt Zeilen in die Quellenpostgresql,mysql,sqliteundmariadbein, und DDL wird unterstützt (siehe unten). - DDL (
CREATE,ALTER,DROP) wird unterstützt und an den Trino- oder den direkten Pfad weitergeleitet; die neue Tabelle wird im Kompilierungskontext registriert und ist sofort abfragbar.COPY ... TO STDOUT(Export) undCOPY ... FROM STDIN(Import) werden in den Formatentextundcsvunterstützt. - Abfragen an
information_schemaundpg_catalogwerden abgefangen und aus einem DuckDB-Katalog-Shim beantwortet — Tools zur Schemaerkennung funktionieren korrekt.
JDBC-Treiber¶
Der JDBC-Treiber von Provisa verwendet Arrow Flight als zugrunde liegenden Transport. Er ist der empfohlene Weg für BI-Tools mit einem JDBC-Verbindungsassistenten.
Verbindung¶
Laden Sie provisa-jdbc.jar herunter (immer die neueste Version) und fügen Sie sie dem Treiberpfad Ihres Tools hinzu.
JDBC-URL:
Die Authentifizierung verwendet die standardmäßigen JDBC-Eigenschaften user / password. Provisa authentifiziert die Anmeldedaten beim konfigurierten Authentifizierungsanbieter und weist die Rolle zu — der Client wählt seine Rolle nicht selbst.
Einrichtung von BI-Tools¶
Tableau
- Verwalten → Treiber → Provisa JDBC installieren
- Verbinden → Andere Datenbanken (JDBC)
- URL:
jdbc:provisa://localhost:8815 - Geben Sie bei Aufforderung Ihren Benutzernamen und Ihr Passwort ein
DBeaver (JDBC-Weg — für den pgwire-Weg siehe oben)
- Datenbank → Neue Verbindung → JDBC
- Treiber:
provisa-jdbc.jarhinzufügen - URL:
jdbc:provisa://localhost:8815 - Geben Sie Ihren Benutzernamen und Ihr Passwort im Tab „Authentifizierung“ ein
Power BI — verwenden Sie das ODBC-Gateway mit der Provisa-JDBC-ODBC-Brücke (im Installationsprogramm enthalten).
Arrow-Flight-Clients¶
Arrow Flight (Port 8815) ist der empfohlene Weg für Datentools, die es unterstützen. Ergebnisse werden als Arrow-RecordBatches gestreamt, ohne im Speicher von Provisa materialisiert zu werden.
Python (provisa-client)¶
Der empfohlene Python-Weg — kapselt sowohl GraphQL als auch Arrow Flight:
from provisa_client import ProvisaClient
client = ProvisaClient("http://localhost:8001", username="alice", password="secret")
# Arrow Flight → pyarrow Table (high-throughput, streaming)
table = client.flight("SELECT id, amount FROM sales.orders")
# Arrow Flight → pandas DataFrame
df = client.flight_df("SELECT id, amount FROM sales.orders")
# GraphQL → DataFrame
df = client.query_df("{ orders { id amount } }")
Die vollständige Referenz, einschließlich DB-API 2.0, SQLAlchemy-Dialekt und ADBC, finden Sie unter docs/python-client.md.
Python (rohes PyArrow)¶
import pyarrow.flight as flight
client = flight.connect("grpc://localhost:8815")
ticket = flight.Ticket(b'{"query": "SELECT id, amount FROM sales.orders"}')
df = client.do_get(ticket).read_all().to_pandas()
Flight trägt seine Anmeldedaten im JSON-Payload, als Feld token — ein Provider-Bearer-Token oder ein persönliches Zugriffstoken. Sowohl der Handshake als auch jedes Ticket akzeptieren es, und beide prüfen es gleich, sodass ein Client, der sich beim Handshake authentifiziert hat, das Token dennoch bei jedem do_get vorlegt. Ein daneben stehendes Feld role fordert eine Rolle an; der Server leitet die zulässigen Rollen der Identität ab und setzt den autorisierten Wert ein, sodass eine Rollenzeichenkette in einem Ticket niemals die Identität ist. (REQ-1263) Siehe Sicherheitsmodell.
ticket = flight.Ticket(json.dumps({
"query": "SELECT id, amount FROM sales.orders",
"token": "provisa_pat_...",
"role": "analyst",
}).encode())
ADBC¶
import adbc_driver_flightsql.dbapi as adbc
conn = adbc.connect("grpc://localhost:8815", db_kwargs={"username": "alice", "password": "secret"})
cursor = conn.cursor()
cursor.execute("SELECT id, amount FROM sales.orders")
table = cursor.fetch_arrow_table()
DuckDB¶
import duckdb, pyarrow.flight as flight
client = flight.connect("grpc://localhost:8815")
ticket = flight.Ticket(b'{"query": "SELECT * FROM sales.orders"}')
arrow_table = client.do_get(ticket).read_all()
conn = duckdb.connect()
result = conn.execute("SELECT region, sum(amount) FROM arrow_table GROUP BY 1").df()
Spark (PySpark)¶
from pyspark.sql import SparkSession
spark = SparkSession.builder \
.config("spark.jars.packages", "org.apache.arrow:flight-core:14.0.0") \
.getOrCreate()
# Use ADBC Flight connector or load via pandas → Spark
Protobuf gRPC (Port 50051)¶
Service-zu-Service-Weg. Provisa generiert beim Start ein .proto pro Rolle — jede Rolle sieht nur die Tabellen und Spalten, auf die sie Zugriff hat.
Laden Sie das Proto für Ihre Rolle herunter:
Verwenden Sie grpc_server_reflection, um das Schema programmatisch zu erkennen.
Jeder RPC muss Anmeldedaten im Metadatenschlüssel authorization tragen — ein Provider-Token oder ein persönliches Zugriffstoken. x-provisa-role fordert eine Rolle aus der zulässigen Menge der Identität an; es ist keine Anmeldeinformation und war es nie. Client-Zertifikate werden unterstützt. Siehe Sicherheitsmodell.
Streaming-Abfragen geben eine Nachricht pro Zeile aus; Mutationen sind unär.
Befehle über Protokolle hinweg aufrufen¶
Ein Befehl ist eine registrierte nachverfolgte Funktion oder ein Webhook — ein aufrufbares Element, das in der semantischen Schicht von Provisa mit einem kind (query oder mutation) und einem impl_kind registriert ist, der beschreibt, wie er ausgeführt wird. Jede Oberfläche leitet Aufrufe über einen einzigen gesteuerten Executor (invoke_tracked_function), der writable_by und die Governance einheitlich durchsetzt (REQ-1156). [tool-verified: provisa/api/data/action_exec.py, provisa/bolt/session.py:786-791, provisa/grpc/server.py:107-135, provisa/pgwire/function_call.py:80-88, provisa/api/flight/server.py:542-554]
impl_kind |
Was ausgeführt wird | Bindungsfelder |
|---|---|---|
source_procedure |
Gespeicherte Prozedur auf einer registrierten Quelle (Standard) | sourceId, schemaName, functionName |
script |
Serverseitiges Skript | script |
http |
Ausgehender HTTP-Aufruf | url, method |
grpc |
Ausgehender gRPC-Aufruf an einen externen Server | target, method |
python |
Von Provisa gehostetes Python-Callable (REQ-885) | callable (z. B. demo.py_functions:random_dataset) |
Wenn ein Befehl ein return_schema deklariert (JSON Schema mit type: array, items: object), liefert er eine Ergebnismenge — jede Oberfläche projiziert ihn dann als typisierten Zeilensatz. Die Demo-Befehle random_python_set (impl_kind python) und random_grpc_set (impl_kind grpc) veranschaulichen sowohl ein gehostetes Callable als auch eine externe gRPC-Brücke, die Zeilen mit Zufallswerten zurückgibt; beide sind in config/provisa-install.yaml registriert. [tool-verified: config/provisa-install.yaml:809-856]
Protokollmatrix¶
| Oberfläche | Syntax | Beispiel |
|---|---|---|
| GraphQL | kind=query → Query-Feld; kind=mutation → Mutation-Feld; mit Domänenpräfix, wenn domain_prefix: true |
{ ps__random_python_set(rows: 5, seed: 42) { id region amount } } |
pgwire / Arrow Flight / MCP run_sql |
SELECT * FROM fn(args) oder SELECT fn(args) |
SELECT * FROM random_python_set(5, 42) |
Cypher HTTP (POST /data/cypher) |
CALL fn(args) YIELD cols |
CALL random_python_set(5, 42) YIELD id, region, amount |
| Bolt (Neo4j Browser / Treiber) | CALL fn(args) — positionale Argumente werden den deklarierten Argumentnamen zugeordnet |
CALL random_python_set(3, 7) |
| Provisa gRPC (Port 50051) | Unär CallCommand(CommandRequest{name, args_json}) → CommandResponse{rows_json} |
grpcurl -d '{"name":"random_python_set","args_json":"{\"rows\":5}"}' ... ProvisaService/CallCommand |
Das Feld kind steuert nur die Platzierung in GraphQL — die SQL-, Cypher-, Bolt- und gRPC-Oberflächen akzeptieren query- und mutation-Befehle identisch.
Apollo Federation¶
Provisa kann als Federation-v2-Subgraph fungieren und sein veröffentlichtes Schema einem Apollo Router oder Apollo Gateway zur Verfügung stellen.
Einrichtung¶
Aktivieren Sie Federation in config.yaml:
Provisa generiert automatisch @key-Direktiven auf Primärschlüsselspalten sowie @external/@provides auf Beziehungen zwischen Subgraphen.
Registrierung bei Apollo Router¶
In Ihrer supergraph.yaml:
subgraphs:
provisa-data:
routing_url: http://provisa:8001/data/graphql
schema:
subgraph_url: http://provisa:8001/data/graphql
Führen Sie rover supergraph compose --config supergraph.yaml aus, um das Supergraph-Schema zu generieren.
Entitäten¶
Provisa beantwortet _entities-Abfragen für Joins zwischen Subgraphen. Jede Tabelle mit einem Primärschlüssel ist automatisch als Federation-Entität auflösbar.
Hasura v2 / DDN Import¶
Siehe docs/import.md für die Migration von Hasura zu Provisa.
Kafka¶
Siehe docs/sources.md für die Konfiguration von Kafka-Topics als schreibgeschützte Tabellen und Senken für Abfrageergebnisse.
Apache-Ossie-Semantikaustausch (REQ-1316)¶
Provisa tauscht semantische Modelle mit Apache Ossie (Spezifikation 0.2.0.dev0, im Inkubationsstatus;
früher Open Semantic Interchange) über einen Grenzadapter aus. Das interne Vokabular von Provisa wird
niemals in das von Ossie umbenannt — die Spezifikation erklärt Breaking Changes für wahrscheinlich,
daher ist die Kopplung auf den Adapter beschränkt.
[tool-verified: provisa/ossie/convert.py docstring lines 7–16; OSSIE_VERSION = "0.2.0.dev0",
provisa/ossie/convert.py line 29]
Export¶
Die kanonische Export-Oberfläche ist ein Live-HTTP-Endpunkt. Er leitet das Ossie-Dokument bei jeder Anfrage aus dem Live-Zustand ab — kein Caching, kein Generierungsschritt.
Die Antwort ist ein YAML-Dokument mit Content-Disposition: attachment; filename=provisa.ossie.yaml.
[tool-verified: ossie_router.py lines 20–33: "THE canonical live Ossie endpoint: the semantic
model derived from live state on every read — no caching, no regeneration step"]
Die Metrics-Seite bietet außerdem eine Schaltfläche Download und eine kopierbare Endpunkt-URL im
Ossie-Interchange-Panel, beide verweisen auf denselben Endpunkt.
[tool-verified: OssieInterchangePanel.tsx lines 64–79: endpointUrl = window.location.origin + OSSIE_ENDPOINT_PATH]
Was exportiert wird¶
Der Adapter bildet Provisa-Objekte wie folgt auf Ossie-Objekte ab:
| Provisa-Objekt | Ossie-Objekt | Hinweise |
|---|---|---|
Table |
dataset |
source = catalog.schema.table; Primär-/Eindeutigkeitsschlüssel aus der Spaltenkonfiguration und UniqueConstraint |
Column |
field |
expression = Spaltenreferenz (ANSI_SQL-Dialekt); Zeitspalten erhalten dimension.is_time: true |
Relationship |
relationship |
Alias wird als Name verwendet, wenn gesetzt; berechnete (funktionsbasierte) Beziehungen werden übersprungen |
Metric |
metric |
name, expression (ANSI_SQL), datatype, description, ai_context — verlustfrei nach Design |
modeling_role / modeling_history |
custom_extensions[].vendor_name="provisa" |
Nur für Roundtrip; andere Tools können dies ignorieren |
[tool-verified: _table_to_dataset, build_ossie_model, provisa/ossie/convert.py lines 90–198;
_table_to_dataset comment at line 153: "Computed (function-target) relationships have no dataset
target — not representable in Ossie; skipping is the defined export boundary"]
Governance, Sicherheit auf Zeilenebene, Lineage und Graph-Semantik werden nicht exportiert. Sie
können zur Roundtrip-Treue im optionalen provisa-Slot der custom_extensions mitreisen, aber der
Austausch hängt nie davon ab, dass andere Tools dies lesen. [tool-verified: provisa/ossie/convert.py docstring lines 13–15]
Unbekannte Provisa-Spaltentypen werden unverändert durchgereicht; der Adapter mappt niemals
stillschweigend auf einen falschen Typ. [tool-verified: _map_datatype, provisa/ossie/convert.py lines 70–77: "Unknown types
pass through verbatim — mapping silently to a wrong type would corrupt the model"]
Typzuordnung¶
[tool-verified: _DATATYPE_MAP, provisa/ossie/convert.py lines 35–65]
| Provisa-/Quelltyp | Ossie-datatype |
|---|---|
varchar, text, char, uuid, string |
string |
int, integer, bigint, smallint, int4, int8, tinyint |
integer |
numeric, decimal, float, double, real |
number |
bool, boolean |
boolean |
date |
date |
time |
time |
timestamp, timestamptz, datetime |
timestamp |
| alles andere | unverändert durchgereicht |
Import¶
Der Import akzeptiert ein Ossie-Dokument (YAML oder JSON) und liefert Registrierungsvorschläge zurück. Nichts wird automatisch registriert — importierte Definitionen umgehen niemals den Überprüfungsschritt.
Der Server analysiert das Dokument mit parse_ossie_model, das die Struktur validiert und eine
OssieImport-Datenklasse zurückgibt, die vorgeschlagene Tabellen, Beziehungen und Metriken als
einfache Dictionaries enthält. Jedes strukturelle Problem führt zu einem 400-Fehler mit einem
pfadbenannten Fehler, z. B. ossie import: missing semantic_model[0].datasets[1].source.
[tool-verified: import_ossie, provisa/api/admin/ossie_router.py lines 36–52:
"Nothing is registered here — imported definitions never bypass registration review"]
Der Überprüfungsbildschirm¶
In der Benutzeroberfläche öffnet die Schaltfläche Import (Metrics-Seite → Ossie-Interchange-Panel)
eine Dateiauswahl. Nachdem das Dokument gesendet und analysiert wurde, öffnet sich ein
Überprüfungsdialog mit jeder vorgeschlagenen Tabelle, Beziehung und Metrik als angehaktes Element.
Der Modellierer kann jedes Element abwählen, um es auszuschließen. Ein Klick auf Anwenden
registriert die angehakten Elemente über die bestehenden Registrierungsmutationen — zuerst die
Tabellen, dann die Beziehungen (die auf Tabellen verweisen), dann die Metriken.
[tool-verified: OssieInterchangePanel.tsx lines 88–165: "Review screen opens with everything
checked; trimming = unchecking"; "Tables first, then relationships... then metrics — each through
the EXISTING registration mutations (REQ-1316)"]
Die in einem von Provisa exportierten Ossie-Dokument gespeicherte Modellierungsrolle und -historie
durchlaufen den Roundtrip beim Import korrekt. [tool-verified: _parse_dataset custom_extensions handling,
provisa/ossie/convert.py lines 287–300: "REQ-1320: round-trip the provisa modeling metadata slot"]
Metriken über Protokolle hinweg (REQ-1319)¶
Die Definition einer gesteuerten Metrik — ihr Ausdruck, ihre Beschreibung und ihr ai_context —
reist mit dem Wert zu jeder Abfrageoberfläche über eine einzige Compiler-Expansion. Es gibt keine
Kopien. Der Compiler reserviert das Schema metrics für den SQL-Zugriff; jedes Protokoll fügt dann
seinen eigenen Metadatenkanal hinzu.
[tool-verified: METRICS_SCHEMA = "metrics", provisa/compiler/metric_expand.py line 43;
REQ-1319 requirement text: "the definition (description, ai_context) travels with the value
everywhere, with no copies"]
SQL / pgwire¶
Adressieren Sie jede Metrik als virtuelle Relation im Schema metrics. Die von Ihnen ausgewählten
Dimensionsspalten werden zum GROUP BY:
-- Grand total
SELECT value FROM metrics.net_revenue;
-- By region
SELECT region, value FROM metrics.net_revenue GROUP BY region;
-- By region and month, filtered
SELECT region, month, value
FROM metrics.net_revenue
WHERE net_revenue.status = 'completed'
GROUP BY region, month;
Der Compiler erweitert die Form metrics.<name> zum tatsächlichen gruppierten Aggregat, bevor die
Governance ausgeführt wird. Spaltenbeschreibungen werden als pg_description-Einträge dargestellt,
sodass DBeaver und \d+ von psql sie anzeigen. [tool-verified: metric_semantic_sql, provisa/compiler/metric_expand.py lines 52–70;
REQ-1319: "description surfaced via pg_description"]
SELECT * wird abgelehnt — benennen Sie die Spalten explizit.
[tool-verified: expand_metric_query, provisa/compiler/metric_expand.py lines 302–306]
GraphQL¶
Metriken werden innerhalb des Wurzelfelds _aggregate als metrics-Block projiziert.
[inferred: per REQ-1319; aggregate_gen.py not read in this session]
Der Definitionstext (description, ai_context) erscheint in der GraphQL-Introspektionsdokumentation,
sodass schema-bewusste Tools und Codegenerierung ihn automatisch aufnehmen.
[inferred: per REQ-1319: "definition in introspection docs"]
MCP (KI-Agenten)¶
Zwei Tools stellen Metriken für MCP-Clients bereit:
list_metrics— liefert alle für die Sitzung sichtbaren gesteuerten Metriken mitname,descriptionundai_context.query_metric— akzeptiert einen Metriknamen sowie eine Dimensionsliste und ruft den semantischen SQL-Pfad des Compilers auf, wobei das Aggregatergebnis zurückgegeben wird.
[inferred: per REQ-1319: "MCP: list_metrics and query_metric tools carrying ai_context, so agents
select governed meanings instead of composing aggregation SQL"; provisa/api/mcp/tools.py not
read in this session]
Agenten, die list_metrics vor dem Erstellen einer Abfrage aufrufen, wählen eine gesteuerte Metrik
nach Namen aus, anstatt Aggregations-SQL von Hand zu schreiben. Das Feld ai_context ist der Ort,
an dem der Definitionstext platziert wird, der die korrekte Auswahl leitet.
Arrow Flight¶
Metriken sind als Metric-Flight-Deskriptoren adressierbar, die Arrow-Tabellen zurückgeben.
[inferred: per REQ-1319: "Arrow Flight: metric flight descriptors returning Arrow tables";
provisa/api/flight/catalog.py not read in this session]
Verwenden Sie dieselbe SQL-Form metrics.<name> über den Standard-Flight-SQL-Ticket-Pfad.
Bolt / Cypher (Neo4j Browser)¶
Rufen Sie eine Metrik über die Prozedur provisa.metric() auf:
[inferred: per REQ-1319: "Bolt/Cypher: a provisa.metric() procedure"; the procedure signature is inferred from the REQ text and not verified against provisa/bolt/session.py in this session]
Fakten- und Dimensionstabellen tragen im föderierten Graphen die Knotenbeschriftungen :Fact und
:Dimension, sodass Bloom die Sternform automatisch darstellt.
[inferred: per REQ-1319 and REQ-1320: "federated graph labels nodes :Fact/:Dimension so Bloom
renders the star"; provisa/cypher/label_map.py not read in this session]
Anfragen in natürlicher Sprache¶
Der NL-Schema-Matcher löst das Metrik-Vokabular in Fragen in natürlicher Sprache direkt zu einer
Metrik plus Dimensionen auf und generiert dann semantisches SQL. [tool-verified: resolve_metric,
provisa/nl/schema_matcher.py is exercised in test_nl_metrics.py lines 76–78:
sql = matcher.resolve_metric("What is the total revenue by region?") →
"SELECT region, value FROM metrics.total_revenue GROUP BY region"]
Faktentabellen werden im NL-Prompt mit [fact] gekennzeichnet; Dimensionstabellen mit [dimension].
Der Matcher bevorzugt bei der Auflösung von Fragen Join-Pfade von Fakt zu Dimension.
[tool-verified: test_format_entities_tags_star_roles, tests/unit/test_nl_metrics.py lines 129–132:
assert "table: orders [fact] fields: amount" in block]
Streaming¶
Kombinieren Sie view_metrics mit materialize und einer Kafka-Senke, um eine Push-on-Change-
Metrikausgabe mit der bestehenden Materialisierungsmaschinerie zu erzeugen. Es ist keine neue
Pipeline erforderlich.
[inferred: per REQ-1319: "Streaming: view_metrics + materialize + Kafka sink yields push-on-change
metrics from existing machinery"; implementation not verified beyond the requirement text]
Observability (OTel)¶
Metrikauswertungen werden verfolgt und können als OpenTelemetry-Metriken exportiert werden. [inferred: per REQ-1319: "Observability: metric evaluations traced and exportable as OTel metrics"; OTel integration code not read in this session]