Quelltypen¶
Ausführungsmodell¶
Jede Abfrage wird letztlich über die Federation-Engine ausgeführt, die Federation über alle Quellen hinweg bereitstellt. Quellen fallen basierend auf ihrer Konnektivität in drei Kategorien. [tool-verified: provisa/core/models.py lines 84–132] (REQ-550)
| Kategorie | Hat direkten Treiber | Hat föderierten Connector | Beispiele |
|---|---|---|---|
| Direktfähig | Ja | Ja | PostgreSQL, MySQL, MariaDB, SingleStore, SQL Server, Oracle, DuckDB |
| Nur Federation | Nein | Ja | Redshift, Druid, Exasol, Hive, Iceberg, Delta Lake, Hive (S3-gestützt) |
| Direktlesen (Replikat) | Ja | Ja | Snowflake, Databricks, ClickHouse — Treiber liest Daten und landet ein Replikat; Abfragen laufen gegen das Replikat in der aktiven Engine |
| Materialisieren → Federation | Nein | Nein | REST/OpenAPI, Remote-GraphQL, gRPC, Neo4j Cypher, SPARQL, WebSocket, RSS, CSV, SQLite, Parquet, Ingest (Push-Empfänger), GovData, SharePoint, Splunk |
Direktfähige Quellen führen Einzelquellen-Abfragen über ihren nativen Treiber aus (unter 100 ms) und umgehen dabei die Federation-Engine (REQ-027, REQ-229). Sie behalten volle Connector-Unterstützung und nehmen an der Federation teil, wenn sie mit anderen Quellen gejoint werden (REQ-028).
Nur-Federation-Quellen werden immer über die Federation-Schicht abgefragt. Es existiert kein direkter Treiber (REQ-229).
Direktlesen (Replikat)-Quellen haben einen DirectDriver, der nativ aus dem Warehouse liest (wo verfügbar Arrow-nativ), ein Replikat in den Materialisierungs-Store der aktiven Engine landet, und Abfragen laufen dann gegen dieses Replikat. Siehe Warehouses als benannte Quellen.
Materialize-Quellen haben keinen föderierten Connector. Provisa ruft ihre Daten ab (beim Start oder zur Abfragezeit) und cacht sie als Parquet in S3 oder in PostgreSQL, wodurch sie für quellenübergreifende Abfragen durch die Federation-Engine erreichbar werden (REQ-309).
Alle Quellen¶
Provisa registriert 54 Quelltypen. Die folgenden Tabellen decken alle 54 ab; der Index ist die Zählung. [tool-verified: provisa/core/models.py SourceType; Kaggle zählt als eigenständige Quelle, obwohl es intern über den files-Connector registriert]
| # | Gruppe | Quelltypen |
|---|---|---|
| 1–13 | RDBMS | postgresql, mysql, mariadb, singlestore, sqlserver, oracle, duckdb, cockroachdb, yugabytedb, greenplum, tidb, firebird, airport |
| 14–20 | Cloud-Data-Warehouses | snowflake, bigquery, databricks, redshift, fabric, synapse, trino |
| 21–25 | Analytics / OLAP | clickhouse, druid, exasol, elasticsearch, pinot |
| 26–30 | Data-Lake / offene Tabellenformate | iceberg, delta_lake, hudi, hive, hive_s3 |
| 31–33 | NoSQL | mongodb, cassandra, redis |
| 34–36 | Streaming | kafka, websocket, rss |
| 37 | Push-Empfänger | ingest |
| 38–39 | Graph & Semantic | neo4j, sparql |
| 40–43 | Dateibasiert | sqlite, csv, parquet, files |
| 44–45 | Observability & Sonstiges | google_sheets, prometheus |
| 46–47 | Enterprise-SaaS | sharepoint, splunk |
| 48–50 | API-Quellen | openapi, graphql_remote, grpc_remote |
| 51 | GovData | govdata |
| 52–53 | Data-Quality-Checker | soda, great_expectations |
| 54 | Kaggle-Datasets | Kaggle (über das Sources-Formular bereitgestellt; registriert als files-Quelle — siehe Kaggle-Datasets) |
Referenz für jeden Quelltyp, den Provisa unterstützt. „Direkter Treiber" bedeutet, dass Einzelquellen-Abfragen nativ gegen die Quelle ausgeführt werden (unter 100 ms) (REQ-027). „Connector-Name" ist der föderierte Connector, der verwendet wird, wenn die Quelle an Mehrquellen-JOINs teilnimmt (REQ-028). [tool-verified: provisa/core/source_registry.py SOURCE_TO_DIALECT; provisa/federation/trino_connectors.py trino_connector_name]
RDBMS¶
| Quelltyp | Direkter Treiber | Connector-Name | Dialekt | Mutations |
|---|---|---|---|---|
postgresql |
asyncpg | postgresql | postgres | Ja |
mysql |
aiomysql | mysql | mysql | Ja |
mariadb |
aiomysql | mariadb | mysql | Ja |
singlestore |
— | singlestore | singlestore | Federiert |
sqlserver |
aioodbc | sqlserver | tsql | Ja |
oracle |
oracledb | oracle | oracle | Ja |
duckdb |
duckdb | memory | duckdb | Ja |
cockroachdb |
asyncpg (pg wire) | postgresql | postgres | Ja |
yugabytedb |
asyncpg (pg wire) | postgresql | postgres | Ja |
greenplum |
asyncpg (pg wire) | postgresql | postgres | Ja |
tidb |
aiomysql (mysql wire) | mysql | mysql | Ja |
firebird |
— | — (DuckDB-Erweiterung) | — | Nein |
airport |
— | — (DuckDB-Erweiterung) | — | Nein |
Wire-kompatible Datenbanken verwenden den JDBC-Treiber, den nativen Async-Treiber und den Dialekt eines Basis-Wire-Protokolls wieder — CockroachDB, YugabyteDB und Greenplum reiten auf dem PostgreSQL-Wire; TiDB reitet auf dem MySQL-Wire. Sie benötigen nur Registry-Einträge, keinen neuen Connector-Code. [tool-verified: provisa/core/source_registry.py _PG_WIRE_TYPES, _MYSQL_WIRE_TYPES] (REQ-950)
firebird (Firebird 3/4/5) und airport (Arrow-Flight-Server) sind registrierte Quelltypen, die vor Ort über DuckDB-Community-Erweiterungen erreicht werden, wenn DuckDB die aktive Engine ist — kein direkter Treiber, kein föderierter Connector. [tool-verified: provisa/core/models.py lines 44, 93] (REQ-899)
Cloud-Data-Warehouses¶
[tool-verified: executor/drivers/snowflake.py, executor/drivers/databricks.py, executor/drivers/registry.py]
| Quelltyp | Direkter Treiber | Connector-Name | Dialekt | Mutations | Hinweise |
|---|---|---|---|---|---|
snowflake |
SnowflakeDriver | snowflake | snowflake | Federiert | Liest über snowflake-connector-python; landet Replikat; account/warehouse/role in federation_hints (REQ-988) |
bigquery |
— | bigquery | bigquery | Federiert | Kein DirectDriver; erreicht über Federation-Engine oder BigQuery-Engine-ATTACH |
databricks |
DatabricksDriver | delta_lake | databricks | Federiert | Liest über databricks-sql-connector (Cloud Fetch, Arrow); landet Replikat; http_path erforderlich in federation_hints (REQ-987) |
redshift |
— | redshift | redshift | Federiert | — |
fabric |
MssqlWarehouseDriver | — | tsql | Federiert | Microsoft Fabric Warehouse; T-SQL über TDS, Azure-AD-Auth; landet Replikat (REQ-995) |
synapse |
MssqlWarehouseDriver | — | tsql | Federiert | Azure Synapse SQL; T-SQL über TDS, Azure-AD-Auth; landet Replikat (REQ-995) |
trino |
SQLAlchemyDriver | — | — | Federiert | Entfernter Trino-/Presto-Koordinator, gelesen über den SQLAlchemy-Trino-Dialekt; landet Replikat auf jeder Engine (REQ-994) |
Analytics / OLAP¶
[tool-verified: executor/drivers/clickhouse.py]
| Quelltyp | Direkter Treiber | Connector-Name | Dialekt | Mutations | Hinweise |
|---|---|---|---|---|---|
clickhouse |
ClickHouseDriver | clickhouse | clickhouse | Federiert | Liest über clickhouse-connect (HTTP); secure: "true" in federation_hints für TLS (REQ-986) |
druid |
— | druid | druid | Nein | — |
exasol |
— | exasol | exasol | Nein | — |
elasticsearch |
HTTP (native Engines) | elasticsearch (Trino) | — | Nein | Auf Trino liest der Connector sie, seine Eigenschaften aus der Mapping-DSL des Typs [tool-verified: trino_connectors.py:309]; auf jeder anderen Engine liest Provisa den Index über HTTP (Indizes und Mapping für Register Table, ein Scroll-Read zum Landen) und landet die Zeilen [tool-verified: provisa/elasticsearch/fetch.py, provisa/events/source_loader.py make_elasticsearch_loader] (REQ-1672) |
pinot |
— | pinot | — | Nein | Trino-pinot-Connector; pinot.controller-urls = Host:Port des Pinot-Controllers [tool-verified: trino_connectors.py:199] |
Data-Lake / offene Tabellenformate¶
Diese Quelltypen sind nur-Federation — kein direkter Treiber, kein Dialekt. [tool-verified: LAKE_ONLY_SOURCES in provisa/core/source_registry.py] (REQ-229)
| Quelltyp | Connector-Name | Time Travel | Hinweise |
|---|---|---|---|
iceberg |
iceberg | Ja (as_of-Argument, REQ-372) |
— |
delta_lake |
delta_lake | Ja (as_of-Argument, REQ-372) |
— |
hive |
hive | Nein | — |
hudi |
— (ClickHouse-Hudi-Engine, Zero-Copy — REQ-1178) |
Nein | Kein föderierter Connector; wird vor Ort erreicht, wenn ClickHouse die aktive Engine ist |
hive_s3 |
hive | Nein | S3-gestütztes Hive |
NoSQL¶
mongodb, cassandra und redis haben Trino-Connectors (redis baut seine Eigenschaften aus der Mapping-DSL des Typs). [tool-verified: provisa/federation/trino_connectors.py; provisa/core/models.py] (REQ-017, REQ-1097)
| Quelltyp | Connector-Name | Mutations |
|---|---|---|
mongodb |
mongodb | Nein |
cassandra |
cassandra (Trino); CQL-Read über cassandra-driver auf jeder anderen Engine | Nein |
redis |
redis (Trino); HTTP-freier redis-py-Read auf jeder anderen Engine | Nein |
Streaming¶
| Quelltyp | Mechanismus | Mutations |
|---|---|---|
kafka |
Föderierter Kafka-Connector; Schema über Confluent Schema Registry (Avro, Protobuf, JSON Schema), manuelle Definition oder Stichproben-Inferenz (REQ-147, REQ-150) | Nur Sink (REQ-176) |
websocket |
Externer WebSocket-Feed — verbinden, abonnieren, Ereignisse empfangen; Ergebnisse materialisiert (REQ-338) | Nein |
rss |
RSS-2.0-/Atom-Feed — pollen, Watermark nach pubDate/updated; Ergebnisse materialisiert (REQ-342, REQ-343) | Nein |
Push-Empfänger¶
| Quelltyp | Mechanismus | Mutations |
|---|---|---|
ingest |
Externe Dienste POSTen JSON-Ereignisse; Ergebnisse materialisiert (REQ-331, REQ-335) | Nein |
Graph & Semantic¶
| Quelltyp | Mechanismus | Mutations |
|---|---|---|
neo4j |
Cypher über HTTP-API, Ergebnisse in PostgreSQL gecacht (REQ-295) | Nein |
sparql |
SPARQL-1.1-POST, Ergebnisse in PostgreSQL gecacht (REQ-297) | Nein |
Dateibasiert¶
Zwei Mechanismen decken Dateien ab. Beide verwenden das Feld path statt host/port. [tool-verified: provisa/core/models.py] (REQ-553)
Einzeldatei-Quellen — sqlite, csv, parquet richten path auf eine Datei.
| Quelltyp | Transporte | Mutations |
|---|---|---|
sqlite |
lokal | Ja |
csv |
lokal | Nein |
parquet |
lokal, s3:// |
Nein |
Private Buckets benötigen Zugangsdaten (AWS-Region und Keys aus der Umgebung). Für CSV über s3:// oder http(s)://, oder um viele Dateien auf einmal zu registrieren, verwenden Sie die files-Quelle. [tool-verified: provisa/file_source/source.py]
files-Quelle — richtet path auf ein Glob-Muster, durchläuft es rekursiv und registriert das Verzeichnis als föderierten Katalog von Tabellen. Sie liest viele Formate über viele Transporte; die untenstehenden Mengen stammen vom File-Connector (kenstott/calcite-Fork). [tool-verified: provisa/core/catalog.py files branch and provisa/core/models.py SOURCE_TO_CONNECTOR; Format- und Transportlisten vom Calcite-file-Adapter — FileSchema.java, storage/StorageProviderFactory.java]
| Formate | Transporte |
|---|---|
| CSV, TSV, JSON, YAML, Excel (XLS/XLSX), Parquet, Arrow und in Tabellen konvertierte Dokumente — HTML, Markdown, DOCX, PPTX | Lokales Dateisystem, HTTP(S), s3://, hdfs://, ftp:///ftps://, sftp://, iceberg://, SharePoint (REST und Microsoft Graph) |
- id: sales_files
type: files
path: s3://bucket/sales/**/*.csv # glob; local and http(s):// also supported
Auf der DuckDB-Engine wird files nativ gelesen — eine read_csv_auto-Scanner-View pro <table>.csv unter dem aufgelösten Verzeichnis (REQ-229) [tool-verified: provisa/federation/connector_duckdb.py DuckDBFilesConnector]. Auf einer Engine ohne eigenen files-Connector landen Zeilen über denselben connector-gebündelten Calcite-pgwire-Server (pgwire-file), den auch sharepoint/splunk verwenden (REQ-954) — siehe Enterprise-SaaS-Connectors unten. Die End-to-End-UI-Abdeckung (Sources-Formular → Register Table → SQL-Abfrage) und der pgwire-Landepfad sind in REQ-1694 nachgewiesen.
Kaggle-Datasets (REQ-1780, REQ-1781, REQ-1782, REQ-1783)¶
Kaggle ist eine Datei-Download-Plattform. Ein bereitgestellter Kaggle-Datensatz registriert sich als Quelle vom Typ files und wird über denselben pgwire-file-Connector abgefragt, den jede andere files-Quelle verwendet — es gibt keinen kaggle-SourceType im Enum. [tool-verified: provisa/kaggle/downloader.py; provisa/core/models.py SourceType — kein kaggle-Literal]
Einen Datensatz hinzufügen. Öffnen Sie Sources → Subscriptions → Kaggle. Das Formular durchläuft zwei sequenzielle Schritte, da Kaggles eigener Dataset-Suchendpunkt Auth erfordert — die Auswahl kann nicht erscheinen, bevor das Token validiert ist. [tool-verified: provisa-ui/src/pages/sources/KaggleFormSection.tsx] (REQ-1783)
- Token — geben Sie ein Kaggle-API-Token ein und klicken Sie auf „Validate". Die Validierung ruft
POST https://www.kaggle.com/api/v1/datasets/create/newmit leerem Body auf. Ein401bedeutet ungültig; jede andere Antwort bedeutet gültig (Kaggles eigene Payload-Validierung greift, bevor irgendein Datensatz erstellt wird — nichts wird persistiert). [tool-verified:provisa/kaggle/client.pyvalidate_token] (REQ-1782) - Auswahl — ein Live-Search-as-you-type-Feld fragt
GET /api/v1/datasets/listab. Jedes Ergebnis zeigt Dataset-Titel und -Beschreibung. Wählen Sie eines aus und klicken Sie auf „Add Dataset".
Ein Klick auf „Add Dataset" lädt das Bundle von GET /api/v1/datasets/download/{owner}/{ref} herunter, entpackt CSV- und Parquet-Mitglieder nach <PROVISA_DATA_DIR>/kaggle/<owner>/<ref>/<file-stem>/<file-name> und erstellt eine Quelle vom Typ files, deren path dieses Wurzelverzeichnis ist. Das Token wird serverseitig nie gespeichert. [tool-verified: provisa/kaggle/downloader.py stage_dataset; provisa-ui/src/pages/sources/KaggleFormSection.tsx handleConfirmDataset] (REQ-1780, REQ-1781)
Nach dem Hinzufügen der Quelle registrieren Sie deren Tabellen über den normalen Register-Table-Bildschirm. Die rekursive Verzeichniserkennung des pgwire-file-Connectors listet jede Datei als eigene Tabelle — derselbe Mechanismus, den jede andere files-Quelle verwendet (REQ-1690). (REQ-1783)
v1-Einschränkung. Ein Bundle mit einer .sqlite- oder .db-Datei wird rundweg mit einer klaren Fehlermeldung abgelehnt. Nur CSV- und Parquet-Dateien werden bereitgestellt. [tool-verified: provisa/kaggle/downloader.py UnsupportedKaggleDataset, _UNSUPPORTED_EXTENSIONS]
Tabellenbenennung. Jede Datei landet in ihrem eigenen <file-stem>/-Unterverzeichnis unter der Dataset-Wurzel. Der pgwire-file-Connector benennt die resultierende Tabelle <subdir>__<stem> nach SMART_CASING-Normalisierung. Zum Beispiel: StatewiseTestingDetails.csv landet unter statewise_testing_details/StatewiseTestingDetails.csv und wird zur Tabelle statewise_testing_details__statewise_testing_details. Der verdoppelte Stem ist bei Einzeldatei-Datasets zu erwarten. Ein Multi-Datei-Dataset erzeugt ein Paar pro Datei: orders__orders, customers__customers. (REQ-471)
Aktualisieren. Um einen Datensatz erneut abzurufen, nachdem Kaggle eine neue Version veröffentlicht hat, rufen Sie die GraphQL-Mutation refreshKaggleSource mit der Quell-ID und einem gültigen Token auf. Dies stellt die Dateien vor Ort erneut bereit und leert den pgwire-file-Endpunkt-Cache, sodass der Connector bei seiner nächsten Abfrage etwaige Schemaänderungen übernimmt. Die zur Erstellungszeit in federation_hints gespeicherten kaggle_owner und kaggle_ref identifizieren, welcher Datensatz erneut abgerufen werden soll. [tool-verified: provisa/api/admin/schema_mutation.py refresh_kaggle_source] (REQ-1780)
Kein statischer YAML-Konfigurationspfad. Kaggle-Quellen werden nur über das Sources-Formular erstellt. Eine nach YAML exportierte Kaggle-Quelle erscheint als type: files mit kaggle_owner und kaggle_ref in federation_hints. Ein erneuter Download von Kaggle erfordert den UI-Refresh-Flow oder die Mutation refreshKaggleSource — das Ausrichten des YAML-path auf ein vorab bereitgestelltes Verzeichnis ist die Alternative für air-gapped Umgebungen.
Observability & Sonstiges¶
prometheus hat einen Trino-Connector (Eigenschaften aus der Mapping-DSL des Typs gebaut). google_sheets ist ein registrierter Quelltyp ohne Trino-Connector und materialisiert über die API-Cache-Pipeline. [tool-verified: provisa/federation/trino_connectors.py:314; provisa/core/models.py lines 87–88]
| Quelltyp | Connector-Name | Mutations |
|---|---|---|
google_sheets |
— (materialisiert) | Nein |
prometheus |
prometheus | Nein |
Enterprise-SaaS-Connectors¶
SharePoint und Splunk registrieren sich über Apache-Calcite-Connectors (kenstott/calcite-Fork). Keiner hat einen direkten Treiber — Provisa startet den mitgelieferten Calcite-pgwire-Server des Connectors (pgwire-sharepoint, pgwire-splunk) und erreicht ihn als generischen PostgreSQL-Endpunkt. Auf der DuckDB-Engine wird dieser Endpunkt live über die postgres-Erweiterung angehängt: Register Table listet die Tabellen des Connectors aus dem angehängten Katalog, Abfragen lesen den Connector vor Ort, und Filter und Projektionen werden zu Calcite heruntergeschoben (REQ-1690) [tool-verified: provisa/federation/connector_duckdb.py _DuckDBPgwireConnector]. Jede andere Engine landet die Zeilen im Materialisierungs-Store für die Federation (REQ-954). Die Bundles werden pro OS/Architektur aus dem gepinnten kenstott/calcite-Release abgerufen (pgwire-<connector>-<version>-<os>-<arch>.tar.gz; macOS arm64, Linux x86_64, Windows x86_64) [tool-verified: provisa/runtime_deps/pgwire_bundles.py]. Beide Connectors aktivieren immer Groß-/Kleinschreibung-unabhängigen Namensabgleich, entsprechend der eigenen case-insensitiven Semantik des jeweiligen Produkts (REQ-725, REQ-730). [tool-verified: provisa/core/models.py lines 99–100; provisa/federation/trino_connectors.py lines 223–286]
sharepoint¶
SharePoint-Listen werden als Schemas aufgezählt und als abfragbare Tabellen offengelegt (REQ-726, REQ-731). Zwei Auth-Methoden: CLIENT_CREDENTIALS (Standard) und zertifikatbasiert über ein PFX-Zertifikat (REQ-727). Secret-Werte in mapping werden über die Secrets-Engine aufgelöst, bevor sie den Connector erreichen (REQ-729). [tool-verified: provisa/federation/trino_connectors.py lines 230–252]
| Quellfeld | Connector-Eigenschaft | Hinweise |
|---|---|---|
base_url oder host |
site-url |
SharePoint-Site-URL |
username |
client-id |
Azure-App-Client-ID |
password |
client-secret |
Azure-App-Client-Secret |
database |
tenant-id |
Azure-Tenant-UUID |
mapping.auth_type |
auth-type |
CLIENT_CREDENTIALS (Standard) oder CERTIFICATE |
mapping.certificate_path |
certificate-path |
PFX-Pfad bei auth_type: CERTIFICATE — muss ABSOLUT sein |
mapping.certificate_password |
certificate-password |
PFX-Passwort — der Key muss vorhanden sein, leerer String bei einer passwortlosen PFX |
Zertifikats-Auth auf den Nicht-Trino-Engines trägt zwei zusätzliche Regeln, beide beim Aufbau des model.json-Operanden des Calcite-pgwire-Servers durchgesetzt (REQ-1693). certificate_path muss absolut sein: Der Server läuft mit seinem Bundle-Verzeichnis als Arbeitsverzeichnis, sodass ein relativer Pfad innerhalb des Runtime-Deps-Caches aufgelöst wird und die PFX nicht gefunden wird. certificate_password muss in mapping vorhanden sein, selbst wenn die PFX kein Passwort hat — in dem Fall ist es der leere String —, denn der Calcite-Adapter lehnt ein Null-Passwort rundweg ab, und ein fehlender Key wird als Konfigurationsfehler behandelt statt stillschweigend als leeres Passwort gelesen. Ein fehlender oder relativer Wert löst MissingConnectorConfig mit Nennung des Felds aus. [tool-verified: provisa/federation/pgwire_replica.py _sharepoint_operand]
Wenn der Connector information_schema.columns nicht offenlegt, registrieren Sie die Tabelle mit expliziten Spaltendefinitionen (aus der Microsoft-Graph-API) über die registerTable-Mutation (REQ-732).
- id: hr-sharepoint
type: sharepoint
base_url: https://kenstott.sharepoint.com
username: ${env:SP_CLIENT_ID}
password: ${env:SP_CLIENT_SECRET}
database: ${env:SP_TENANT_ID}
mapping:
auth_type: CLIENT_CREDENTIALS
Zertifikats-Auth, mit dem absoluten Pfad und dem immer vorhandenen Passwort:
- id: hr-sharepoint
type: sharepoint
base_url: https://kenstott.sharepoint.com
username: ${env:SP_CLIENT_ID}
database: ${env:SP_TENANT_ID}
mapping:
auth_type: CERTIFICATE
certificate_path: /etc/provisa/certs/sharepoint.pfx
certificate_password: ${env:SP_CERT_PASSWORD}
splunk¶
Splunk-Suchergebnisse sind als Tabellen abfragbar (z. B. internal_server) (REQ-721). Die Connector-URL stammt aus base_url oder wird als https://{host}:{port} mit Standardport 8089 konstruiert (REQ-722). Auth: Ist mapping.use_token true (Standard), wird password als API-Token übergeben; ist es false, werden username und password als separate Zugangsdaten übergeben (REQ-723). [tool-verified: provisa/federation/trino_connectors.py lines 262–286]
| Quellfeld | Connector-Eigenschaft | Hinweise |
|---|---|---|
base_url / host + port |
url |
base_url, sonst https://host:port (Standardport 8089) |
password |
token oder password |
Token, wenn use_token: true |
username |
user |
nur, wenn use_token: false |
database |
app |
auf eine Splunk-App einschränken |
mapping.datamodel_filter |
datamodel-filter |
auf ein Data Model filtern |
mapping.disable_ssl_validation |
disable-ssl-validation |
für selbstsignierte Zertifikate (REQ-724) |
Auf dem pgwire-Replica-Pfad (jede Engine außer Trino) werden dieselben vier optionalen Einstellungen zu den Calcite-model.json-Operanden-Keys app, token/username+password, datamodelFilter und disableSslValidation — die letzten beiden in den Typen, in die SplunkSchemaFactory sie castet, ein String und ein Boolean (REQ-1694). [tool-verified: provisa/federation/pgwire_replica.py _splunk_operand]
- id: ops-splunk
type: splunk
host: splunk
port: 8089
password: ${env:SPLUNK_TOKEN}
mapping:
use_token: true
disable_ssl_validation: true
API-Quellen¶
Registrieren Sie jeden HTTP-Endpunkt als abfragbare Tabelle. [tool-verified: provisa/core/models.py SourceType enum] (REQ-314, REQ-307, REQ-322)
| API-Typ | Discovery | Spaltenableitung |
|---|---|---|
openapi |
OpenAPI-Spec-Parsing (REQ-314, REQ-316) | Primitive → nativ, Objekte → JSONB |
graphql_remote |
Schema-Introspektion (REQ-307, REQ-308) | Primitive → nativ, Objekte → JSONB |
grpc_remote |
Server Reflection (REQ-322, REQ-325) | Primitive → nativ, Objekte → JSONB |
API-Antworten werden abgerufen, in PostgreSQL gecacht (konfigurierbare TTL) und als GraphQL-Typen offengelegt (REQ-309, REQ-318, REQ-327). Gecachte Tabellen nehmen wie jede andere Quelle an föderierten Abfragen teil (REQ-313).
JSONB-Regeln: Komplexe Spalten (Objekte, Arrays), die als JSONB gespeichert werden, sind nicht filterbar (REQ-119). Der Zugriff auf Unterfelder verwendet die ->>-Extraktion in SQL (REQ-151). Beziehungen werden zwischen Tabellen über skalare FK-Spalten deklariert — JSONB-Blob-Spalten sind keine Join-Ziele. Verwenden Sie JSONB-Promotion, um verschachtelte Felder in native skalare Spalten umzuwandeln, wenn Filtern oder Joinen darauf benötigt wird (REQ-119).
GovData¶
Offene Daten der US-Regierung. Der Zugriff ist nach Themengruppierung partitioniert. [tool-verified: provisa/core/models.py lines 543–609]
Jede govdata-Quelle wählt ein Thema. Dieses Thema bestimmt, welche GovData-Schemas offengelegt werden. Die Schemas ref und geo sind immer als Linker-Schemas enthalten — sie werden nicht pro Thema aufgeführt, sind aber immer vorhanden. [tool-verified: provisa/core/models.py line 562–563 comment]
| Thema | Offengelegte Schemas |
|---|---|
COMMERCE |
sec, patents |
ECONOMY |
econ |
EDUCATION |
census, edu |
HEALTH |
health |
CYBER |
cyber_threat, cyber_vuln |
PUBLIC_SAFETY |
crime |
ENVIRONMENT |
lands |
WEATHER |
weather |
GOVERNMENT |
fedregister, fec |
ALL |
Jedes obige Schema |
sources:
- id: federal-commerce
type: govdata
subject: COMMERCE
domain_id: federal-analytics
description: U.S. commerce and securities data
| Feld | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
id |
Ja | — | Eindeutiger Bezeichner |
subject |
Ja | — | Einer der obigen Themenwerte |
domain_id |
Ja | — | Domäne, zu der diese Quelle gehört |
description |
Nein | "" |
Menschenlesbare Beschreibung |
Wo das Passwort einer Quelle lebt¶
Das Passwort einer Quelle wird nie neben den übrigen Verbindungseinstellungen gespeichert. Die
sources-Zeile der Control Plane trägt eine password_ref-Spalte mit einer Referenz —
${env:PG_PASSWORD}, ${secret:SNOWFLAKE_KEY} —, die im Moment aufgelöst wird, in dem die Quelle
angewählt wird, innerhalb der Organisation, in deren Namen die Anfrage läuft (REQ-1695). [tool-verified:
provisa/core/schema_org.py, provisa/core/repositories/source.py]
${env:VAR} liest die Prozessumgebung des Deployments und benötigt keine Bindung. ${secret:NAME}
benennt ein Secret, das einer Organisation gehört, sodass es nur innerhalb der eigenen Operationen
dieser Organisation aufgelöst wird: die Admin-Introspektions-Nahtstellen und das Query-Terminal, das
jede Oberfläche erreicht, stellen diese Bindung her. [tool-verified: provisa/pgwire/_pipeline.py _execute_plan]
Wohin die Referenz zeigt, hängt davon ab, wie die Quelle registriert wurde:
- Aus der Konfiguration. Sie schreiben die Referenz selbst.
${env:VAR}liest die Prozessumgebung des Deployments;${secret:NAME}liest den Vault der Organisation (siehe Secrets). Die Datei ist der Datensatz, und Provisa kopiert die Referenz wortwörtlich inpassword_ref. - Aus dem Sources-Formular. Eine in das Passwortfeld eingegebene Referenz wird ebenfalls wortwörtlich
gespeichert. Ein literales Passwort wird unter
source_<id>_passwordin den Vault der Organisation geschrieben — verschlüsselt gespeichert und nie namentlich zurücklesbar —, und die Zeile behält das${secret:source_<id>_password}, das es benennt. [tool-verified:provisa/api/admin/schema_common.pypersist_source_password]
Das erneute Eintippen des Passworts bei einer bestehenden Quelle rotiert diesen einen Vault-Eintrag,
statt einen zweiten zu erstellen. Das Löschen der Quelle entfernt den Eintrag, den Provisa dafür
geprägt hat, und nur diesen einen: Eine Referenz, die Sie selbst geschrieben haben, benennt ein
Secret, das Ihnen aus eigenen Gründen gehört, also bleibt sie unangetastet.
[tool-verified: provisa/api/admin/schema_mutation.py delete_source]
password_ref wandert nicht zwischen Umgebungen (REQ-1491). Ein Branch oder eine kopierte Umgebung
liefert ihre eigenen Verbindungswerte, und der Vault, den eine Referenz benennt, gehört zu welcher
Umgebung auch immer sie geliefert hat. [tool-verified: provisa/core/env_classes.py BINDING_COLUMNS]
Data-Quality-Checker (REQ-1443)¶
Ein Data-Quality-Checker ist ein Quelltyp, kein Subsystem. Seine Scan-Ausgabe sind Daten: Ein Check-Ergebnis ist eine Beobachtung, sodass es über den gewöhnlichen Quellpfad landet und Kadenz, Freshness, Events, Lineage, Governance, RLS, Grid und Export von jeder anderen Quelle erbt. [tool-verified: provisa/core/models.py lines 110–116 SourceType.soda, SourceType.great_expectations; provisa/events/source_loader.py make_dq_loader]
Zwei werden unterstützt, und die Wahl ist ebenso eine Lizenzfrage wie eine Feature-Frage.
| Quelltyp | Vertrags-Dialekt | Extra | Lizenz | Gehostete Cloud-Plane |
|---|---|---|---|---|
soda |
Soda-Contract-YAML | pip install .[soda] (soda-postgres) |
Elastic License 2.0 | Abgelehnt — siehe unten |
great_expectations |
Expectation-Suite-JSON | pip install .[gx] (great-expectations[postgresql]) |
Apache 2.0 | Erlaubt |
Die Elastic License 2.0 verbietet, die Software Dritten als gehosteten oder verwalteten Dienst bereitzustellen, und Soda innerhalb der SaaS-Plane im Namen eines Mandanten laufen zu lassen ist genau das. config/capabilities.yaml trägt die Aufteilung als cloud_eligible: false auf der soda-Option, und die gehostete Plane liest dieses Flag. Ein gehostetes Deployment, das Soda möchte, erreicht einen vom Betreiber bereitgestellten Soda-Endpunkt, den der Betreiber selbst betreibt. [tool-verified: config/capabilities.yaml lines 197–203]
Provisa bündelt und verlinkt nichts. Der Scan läuft in einem Kind-Interpreter (python -m provisa.dq.worker), dem einzigen Ort, an dem soda_core oder great_expectations importiert wird, sodass ein source-available Checker den Serverprozess nie erreicht und ein Checker-Absturz einen Subprozess tötet statt die Event-Loop. [tool-verified: provisa/dq/runner.py build_command, run_contract]
Die Quelle zeigt auf Provisas eigenen pgwire-Endpunkt. Das ist, was es einem Postgres-Treiber erlaubt, eine Snowflake- oder Iceberg-gestützte Tabelle zu prüfen: Der Checker scannt die föderierte Sicht, nicht das darunterliegende System. Weil Richtlinie auf diese Verbindung angewendet wird, wird die Scan-Identität deklariert statt geerbt — eine gefilterte Zeilenmenge darf nie einen stillschweigend bestehenden Check erzeugen.
sources:
- id: dq
type: soda
domain_id: sales-analytics
description: Soda contract scans over the governed estate
mapping:
host: localhost
port: 5439 # Provisa's pgwire endpoint
database: provisa
user: dq_scanner # the scan identity, declared explicitly
password: ${env:PROVISA_DQ_PASSWORD}
Eine Ergebnistabelle pro Vertrag, und der Vertrag ist die gesamte Registrierung. Die Tabelle trägt dq_contract — den Vertragstext wortwörtlich — und sonst nichts über ihre Form. Spalten, Watermark und Promotions werden alle abgeleitet. [tool-verified: provisa/dq/registration.py derive_checker_table]
tables:
- source_id: dq
schema_name: quality
table_name: orders_scan
domain_id: sales-analytics
change_signal: ttl_probe
cache_ttl: 3600
columns:
- name: scan_id # declared only to carry visible_to; replaced at parse
visible_to: [analyst, admin]
dq_contract: |
dataset: provisa/sales/orders
columns:
- name: customer_id
checks:
- missing:
threshold:
metric: percent
must_be_less_than: 1
checks:
- row_count:
must_be_greater_than: 0
Was die Registrierung aus diesem Text ableitet:
- Lineage. Der Vertrag benennt bereits sein Zieldataset, sodass die Registrierung ihn so parst, wie
extract_inputsSQL parst (REQ-939), und ihn auf die geregelte Tabelle auflöst. Eine Definition, keine zweite Kopie, die driften kann. Ein Vertrag, der ein ungeregeltes Dataset benennt, schlägt bei der Registrierung laut fehl, statt Zeilen zu landen, die niemand angefordert hat. - Spalten. Der Ergebnis-Umschlag gehört dem Checker, nicht dem Betreiber — 16 mitgelieferte Spalten von
scan_idbisdiagnostics. Deklarierte Spalten werden nur für ihrvisible_togelesen, das einstimmig sein muss, und dann ersetzt. [tool-verified:provisa/dq/results.py_ENVELOPE,results_columns] - Watermark.
scan_timewird zum Watermark, was das Landen zu einem Append macht (REQ-982). Scan-Historie akkumuliert ohne Historien-Subsystem. - Promotions.
freshness_max_timestampunddataset_rows_testedwerden aus demdiagnostics-jsonb als typisierte Spalten hochgestuft (REQ-119). Fügen Sie weitere hinzu, wie Sie es bei jeder anderen jsonb-Spalte täten. [tool-verified:provisa/dq/results.pyDQ_PROMOTIONS]
Timing führt keine neuen Felder ein. change_signal plus cache_ttl geben die Poll-Kadenz vor; mv_debounce_quiet und mv_debounce_max_delay fassen einen vorgelagerten Burst zu einem Scan zusammen (REQ-963); eine Kalendergranularität macht ihn periodisch (REQ-962); expected_events hält den Scan zurück, bis seine Eingaben durch das Fenster frisch sind (REQ-961). Die Poll-Schleife ist der Scan-Scheduler.
outcome ist eines von pass, fail, warn, error, skipped. Keines davon ist ein Urteil — Durchsetzung, falls gewünscht, ist eine separate, spätere Deklaration: ein Preflight oder eine materialisierte Sicht über den gelandeten Ergebnissen. Weil eine gelandete Beobachtung keine Determinismus-Verpflichtung trägt (REQ-964), sind hier nichtdeterministische Checks zulässig, die auf einem Preflight-Gate nie sitzen könnten — Anomalie-Score, Trailing-Window-Änderung, Freshness gegen jetzt.
Der Vertrag wird in der UI verfasst, im Data-Quality-Panel der Tabellen-Bearbeitungsoberfläche, und der rohe Vertragstext dort ist immer die Source of Truth. Ein Trockenlauf führt den Vertrag gegen die Live-Tabelle aus und zeigt die Ergebnisse, ohne sie zu landen — so erwischen Sie einen Vertrag, dessen Datasetname an eine unerwartete Stelle aufgelöst wurde und der sonst nichts als bestehende Zeilen landen würde.
Benutzerdefinierte Connectors (REQ-1177)¶
Die nativen Federation-Engines — Postgres, DuckDB und ClickHouse — gewinnen Erreichbarkeit zu einem neuen Quelltyp, wenn ein Betreiber dafür einen Connector in config/custom_connectors.yaml deklariert. Kein Code erforderlich. [tool-verified: provisa/federation/custom_connectors.py load_custom_connectors; provisa/federation/engine.py build_pg_engine, build_duckdb_engine, build_clickhouse_engine]
Connector-Erweiterbarkeit selbst geht dem voraus. Die Trino-Engine ist auf ihrer eigenen Schicht seit Langem erweiterbar — ein generischer JDBC-Connector, parametrisiert pro Quelltyp, ein Katalog-.properties-Body pro Typ, und Provisas eigene benutzerdefinierte Trino-Connector-Plugins (Splunk, SharePoint, Calcite). [tool-verified: provisa/federation/trino_connectors.py _TrinoJdbcConnector, _TRINO_JDBC_TYPES; trino/plugins/trino-splunk, trino/plugins/trino-sharepoint, trino/plugins/trino-calcite] REQ-1177 bringt dieselbe konfigurationsgesteuerte Erweiterbarkeit zu den zwei nativen, clusterlosen Engines, die zuvor eine feste Connector-Menge trugen.
Die Konfiguration wird leer ausgeliefert. Eingebaute Connectors decken die Reichweite von Haus aus ab; alles in dieser Datei ist vom Betreiber verfasst. [tool-verified: config/custom_connectors.yaml line 52: connectors: []] Setzen Sie PROVISA_CUSTOM_CONNECTORS, um auf einen anderen Pfad zu verweisen (nützlich für Tests).
Deskriptor-Arten¶
| Engine | Art | Mechanismus | Was der Deskriptor liefert |
|---|---|---|---|
postgres |
pg_fdw |
SQL/MED (ISO-Standard) | extension, server_options, user_mapping, supports_import, table_options, remote_schema |
duckdb |
duckdb_attach |
INSTALL/LOAD + ATTACH | extension, probe_symbol, attach_template, remote_schema |
duckdb |
duckdb_scan |
INSTALL/LOAD + Scanner-View | extension, probe_symbol, scan_template |
clickhouse |
clickhouse_database |
CREATE DATABASE ENGINE=… (legt automatisch jede entfernte Tabelle offen) |
ch_engine, engine_template |
clickhouse |
clickhouse_table |
CREATE TABLE ENGINE=… pro Tabelle (Spalten aus der Registry) |
ch_engine, engine_template (kann {table} tragen) |
clickhouse |
clickhouse_scan |
CREATE TABLE ENGINE=…, ClickHouse leitet das Schema ab |
ch_engine, engine_template |
Postgres ist generisch. SQL/MED ist ein ISO-Standard, sodass jeder konforme FDW dieselbe DDL-Form teilt: CREATE SERVER … FOREIGN DATA WRAPPER <fdw> OPTIONS(…), optional CREATE USER MAPPING, dann entweder IMPORT FOREIGN SCHEMA (wenn supports_import: true) oder ein explizites CREATE FOREIGN TABLE pro Tabelle (wenn false). Ein pg_fdw-Deskriptor liefert nur die Pro-FDW-Varianz — Erweiterungsname, Server-Options-Keys, User-Mapping-Keys, Import-Flag, Tabellen-Optionen. Jeder standardkonforme FDW ist daher allein aus der Konfiguration ansteuerbar. [tool-verified: provisa/federation/custom_connectors.py GenericPgFdwConnector.details lines 98–125]
DuckDB unterstützt zwei Mechanismen. Eine Erweiterung, die einen Katalog über ATTACH offenlegt, verwendet duckdb_attach; eine, die eine lesende Table-Function offenlegt, verwendet duckdb_scan. Eine Erweiterung, die zu keinem der beiden Muster passt, wird nicht unterstützt. [tool-verified: provisa/federation/custom_connectors.py GenericDuckDbAttachConnector, GenericDuckDbScanConnector]
ClickHouse unterstützt drei Mechanismen, einen pro Integrations-Engine-Form: eine relationale DATABASE-Engine, die automatisch jede entfernte Tabelle offenlegt (clickhouse_database, z. B. Redis/MySQL), eine Pro-Tabelle-Engine, deren Spalten die Registry liefert (clickhouse_table, z. B. die JDBC-/ODBC-Brücke — der engine_template kann einen {table}-Platzhalter tragen, den die Laufzeit bindet), und eine Datei-/Lake-/URL-Engine, deren Schema ClickHouse ableitet (clickhouse_scan, z. B. HDFS/URL). SQLite (DATABASE-Engine, Datei, kein Server) und Hudi (Lakehouse, Zero-Copy) werden OOTB ausgeliefert. [tool-verified: provisa/federation/custom_connectors.py GenericClickHouseDatabaseConnector, GenericClickHouseTableConnector, GenericClickHouseScanConnector; provisa/federation/clickhouse_connectors.py ClickHouseSqliteConnector, ClickHouseHudiConnector] (REQ-1178)
Ein unbekannter kind-Wert schlägt beim Start laut fehl — ein Deskriptor-Tippfehler darf einen Quelltyp nicht stillschweigend unerreichbar machen. [tool-verified: provisa/federation/custom_connectors.py load_custom_connectors lines 178–197]
Probe-Gating¶
Verfügbarkeit wird zur Attach-Zeit gegen den Standard-Discovery-Katalog jeder Engine geprüft:
- Postgres — prüft
pg_extension, dannpg_available_extensions. [tool-verified:provisa/federation/connector_duckdb.py_probe_pg_extensionlines 333–344] - DuckDB — führt
INSTALL/LOADaus und prüftduckdb_functions()auf das deklarierteprobe_symbol. [tool-verified:provisa/federation/connector_duckdb.py_DuckDBExtensionConnector.probelines 160–180] - ClickHouse — prüft
system.table_enginesauf die deklariertech_engine; fehlt sie im Build, schlägt es laut fehl. [tool-verified:provisa/federation/custom_connectors.py_probe_clickhouse_engine]
Eine deklarierte Erweiterung, die nicht installierbar ist, schlägt laut fehl. Kein stiller Skip, kein Fallback. Ein Connector, dessen Probe fehlschlägt, ist für dieses Deployment schlicht nicht aktiv.
Template-Variablen¶
Jeder server_options-Wert, user_mapping-Wert, attach_template und scan_template kann {field}-Platzhalter verwenden. Verfügbare Felder: [tool-verified: provisa/federation/custom_connectors.py _source_fields lines 53–63]
{id}, {host}, {port}, {database}, {username}, {password}, {path}, {schema_name}, {table_name}, plus jeder Key aus federation_hints. DuckDB-Attach-Templates erhalten außerdem {alias} — den internen Katalog-Alias, den Provisa der angehängten Datenbank zuweist.
Ein Template, das ein unbekanntes Feld referenziert, schlägt zur Attach-Zeit laut fehl und macht eine Deskriptor-/Quell-Fehlpassung sichtbar, bevor defektes DDL die Engine erreicht.
Beispiele¶
Postgres — MongoDB über mongo_fdw (kein Schema-Import; Spalten pro Tabelle geliefert)
# config/custom_connectors.yaml
connectors:
- engine: postgres
source_type: mongodb
kind: pg_fdw
extension: mongo_fdw
mechanism: attach_r
server_options:
address: "{host}"
port: "{port}"
user_mapping:
username: "{username}"
password: "{password}"
supports_import: false
table_options:
database: "{database}"
collection: "{table_name}"
DuckDB — Excel-Dateien über read_xlsx (Scan-Table-Function)
- engine: duckdb
source_type: xlsx
kind: duckdb_scan
extension: excel
install_from_community: false
probe_symbol: read_xlsx
scan_template: "read_xlsx('{path}')"
[tool-verified: config/custom_connectors.yaml commented examples, lines 26–50]
Sobald einer der beiden Deskriptoren vorhanden ist, routet die Registrierung einer Quelle mit dem deklarierten source_type über den benutzerdefinierten Connector, vorbehaltlich einer erfolgreichen Probe. Keine weitere Konfigurationsänderung ist nötig.
Warehouses als benannte Quellen¶
Snowflake, Databricks und ClickHouse können unabhängig davon, welche Federation-Engine aktiv ist, als benannte Quellen registriert werden. [tool-verified: executor/drivers/snowflake.py (REQ-988), executor/drivers/databricks.py (REQ-987), executor/drivers/clickhouse.py (REQ-986)]
Bei Registrierung liest Provisa das Warehouse über den DirectDriver der Quelle und landet ein Replikat im Materialisierungs-Store der aktiven Engine. Die Abfrage läuft dann gegen dieses Replikat. Das unterscheidet sich vom traditionellen direktfähigen Pfad (asyncpg, aiomysql), bei dem die Engine vollständig umgangen wird — hier führt die Engine die Abfrage weiterhin aus, aber gegen ein lokales Replikat statt bei jeder Anfrage über die Leitung zum Warehouse.
Reads sind Arrow-nativ, wo das Warehouse es unterstützt: Databricks verwendet Cloud Fetch, Snowflake verwendet fetch_arrow_table, und ClickHouse verwendet die native columnar HTTP-Schnittstelle.
Erweiterte Verbindungsparameter, die die Standardfelder host/port/username/password nicht tragen können, gehen in federation_hints:
sources:
- id: my-databricks
type: databricks
host: my-workspace.azuredatabricks.net
password: ${env:DATABRICKS_TOKEN}
federation_hints:
http_path: /sql/1.0/warehouses/xxxx # required — the SQL Warehouse connection detail
- id: my-snowflake
type: snowflake
host: org.snowflakecomputing.com
username: svc_provisa
password: ${env:SNOWFLAKE_PASSWORD}
federation_hints:
account: myorg-myaccount # required — Snowflake account identifier
warehouse: COMPUTE_WH # optional — virtual warehouse to use
role: PROVISA_ROLE # optional — Snowflake role
- id: my-clickhouse
type: clickhouse
host: ch.example.com
port: 8123
database: analytics
username: default
password: ${env:CLICKHOUSE_PASSWORD}
federation_hints:
secure: "true" # optional — enables TLS on the HTTP interface
Die Registrierung als benannte Quelle ist unabhängig davon, ob dasselbe Warehouse als Federation-Engine gewählt wird. Eine Snowflake-Quelle auf einer DuckDB-Engine landet ein Replikat in DuckDB, nicht in Snowflake.
Cloud-Objekt-/Lake-Daten (Parquet-, CSV-, Iceberg-, Delta-Lake-Dateien auf S3 / GCS / R2) sind ein separater Quelltyp, der vor Ort angehängt wird, wenn die aktive Engine einen ATTACH-Connector für diesen Typ hat. Kein Replikat wird gelandet — die Engine scannt den Objektspeicher direkt. Zugangsdaten für diese Quellen gehen ebenfalls in federation_hints:
sources:
- id: r2-events
type: parquet
path: s3://my-bucket/events/2026/*.parquet
federation_hints:
access_key_id: ${env:R2_ACCESS_KEY}
secret_access_key: ${env:R2_SECRET}
account_id: ${env:R2_ACCOUNT_ID} # Cloudflare R2 account (S3-compatible)
Quellkonfigurationsfelder¶
Alle Quellen teilen eine gemeinsame Menge von Feldern. [tool-verified: provisa/core/models.py Source class, lines 138–204]
| Feld | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
id |
Ja | — | Eindeutiger Bezeichner; alphanumerisch mit Bindestrichen/Unterstrichen |
type |
Ja | — | Quelltyp (siehe obige Tabellen) |
host |
Nein | "" |
Hostname oder IP |
port |
Nein | 0 |
Portnummer |
database |
Nein | "" |
Datenbankname |
username |
Nein | "" |
Benutzername |
password |
Nein | "" |
Passwort; verwenden Sie ${env:VAR} oder ${secret:NAME} statt eines Literals (siehe unten) |
path |
Nein | null |
Dateipfad oder Cloud-URI für dateibasierte und Objekt-/Lake-Quellen |
base_url |
Nein | null |
Basis-URL für OpenAPI-Quellen |
pool_min |
Nein | 1 |
Minimale Connection-Pool-Größe (REQ-052) |
pool_max |
Nein | 5 |
Maximale Connection-Pool-Größe (REQ-052) |
use_pgbouncer |
Nein | false |
Verbindungen über PgBouncer routen (REQ-053) |
pgbouncer_port |
Nein | 6432 |
PgBouncer-Port (REQ-053) |
cache_enabled |
Nein | true |
API-Response-Caching aktivieren |
cache_ttl |
Nein | null |
Cache-TTL in Sekunden; erbt globalen Standard, wenn null |
cache_catalog |
Nein | null |
Föderierter Katalog für API-Cache; Standard ist der eigene Katalog der Quelle |
cache_schema |
Nein | api_cache |
Schema innerhalb des Cache-Katalogs |
naming_convention |
Nein | null |
Überschreibt die globale Namenskonvention für diese Quelle (REQ-194) |
federation_hints |
Nein | {} |
An die Federation-Engine übergebene Session-Eigenschaften und erweiterte Verbindungsparameter für Warehouse-Quellen (REQ-278, REQ-281) |
mapping |
Nein | {} |
Typspezifische Connector-Einstellungen für NoSQL- und SaaS-Quellen (z. B. SharePoint auth_type, Splunk use_token) (REQ-251) |
allowed_domains |
Nein | [] |
Quelle auf bestimmte Domänen beschränken; leer = uneingeschränkt |
description |
Nein | "" |
Menschenlesbare Beschreibung |
Kafka-Quellen¶
Kafka-Topics werden separat unter kafka_sources konfiguriert, verschlüsselt nach der Quell-id einer registrierten kafka-Quelle. [tool-verified: config/provisa.yaml lines 138–151] (REQ-147)
kafka_sources:
- id: kafka-support
topics:
- id: tickets
topic: support.tickets
domain_id: sales-analytics
description: "Inbound support tickets"
default_window: 1h
columns:
- name: id
- name: subject
- name: status
- name: created_at
| Feld | Beschreibung |
|---|---|
id |
Muss der id einer Quelle mit type: kafka entsprechen |
topics[].id |
Logischer Name für dieses Topic innerhalb von Provisa |
topics[].topic |
Kafka-Topic-Name |
topics[].domain_id |
Domäne, zu der dieses Topic gehört |
topics[].description |
Menschenlesbare Beschreibung |
topics[].default_window |
Standard-Zeitfenster für Windowed-Abfragen (z. B. 1h) (REQ-148) |
topics[].columns |
Spaltendefinitionen für das Topic-Schema (REQ-150) |
Spaltensichtbarkeit¶
Das Feld visible_to auf jeder Spalte ist eine Liste von Rollen-IDs, die diese Spalte sehen können. [tool-verified: provisa/core/models.py Column class line 248; config/provisa.yaml lines 39–51]
columns:
- name: email
visible_to: [admin] # only admin role sees this column
- name: region
visible_to: [admin, analyst] # both roles see this column
Spalten, die aus der visible_to-Liste einer Rolle ausgelassen sind, erscheinen nicht im GraphQL-Schema dieser Rolle und können nicht abgefragt oder in Filtern referenziert werden (REQ-039).
Beziehungen¶
Beziehungen verbinden zwei registrierte Tabellen und erscheinen als verschachtelte Felder in GraphQL. [tool-verified: provisa/core/models.py Relationship class lines 323–343; config/provisa.yaml lines 103–110] (REQ-019)
relationships:
- id: orders-to-customers
source_table_id: orders
target_table_id: customers
source_column: customer_id
target_column: id
cardinality: many-to-one
| Feld | Erforderlich | Beschreibung |
|---|---|---|
id |
Ja | Eindeutiger Bezeichner für diese Beziehung |
source_table_id |
Ja | Tabelle, die den Fremdschlüssel trägt |
target_table_id |
Ja | Referenzierte Tabelle; leer bei berechneten Beziehungen |
source_column |
Ja | Spalte auf der Quelltabelle |
target_column |
Ja | Spalte auf der Zieltabelle; leer bei berechneten Beziehungen |
cardinality |
Ja | many-to-one oder one-to-many (REQ-019) |
materialize |
Nein | Erstellt automatisch eine materialisierte Sicht für quellenübergreifende Joins (REQ-158). Bei einer junction-gestützten Kante deckt die Sicht die Zwei-Hop-Traversierung ab, nicht einen direkten Join (REQ-1586) |
refresh_interval |
Nein | MV-Refresh-Intervall in Sekunden (Standard: 300) |
target_function_name |
Nein | DB-Funktionsname für berechnete Beziehungen |
function_arg |
Nein | Welches Funktionsargument den Wert der Quellspalte erhält |
alias |
Nein | Menschenlesbarer Beziehungstyp (z. B. WORKS_FOR) |
graphql_alias |
Nein | Benennt das SDL-Feld, das diese Beziehung auf dem übergeordneten Typ offenlegt. Fehlt es, wird der Name aus dem field_name der Zieltabelle und der Beziehungskardinalität abgeleitet. [tool-verified: provisa/compiler/schema_gen.py:1050] |
disable_cypher |
Nein | Bei true wird diese Beziehung von den Cypher-Graphkanten ausgeschlossen |
source_json_key |
Nein | Extrahiert diesen Key aus der Quellspalte als JSON-Objekt vor dem JOIN |
via_table |
Nein | Registrierter Tabellenname der Junction, die diese Kante durchläuft. Das Setzen macht die Kante junction-gestützt; leer lassen macht sie zu einer Fremdschlüsselkante (REQ-1586) |
via_source_column |
Nein | Junction-Spalte, gepaart mit source_column. Kommagetrennt und positionsbezogen bei einem zusammengesetzten Schlüssel |
via_target_column |
Nein | Junction-Spalte, gepaart mit target_column |
via_type_column |
Nein | Diskriminator-Spalte, wenn eine Junction mehrere Beziehungstypen trägt |
via_type_value |
Nein | Der Diskriminatorwert, auf den diese Kante festgelegt ist |
via_label_source |
Nein | Welche Nominierung den Cypher-Typ benennt: column (der Diskriminatorwert), table (der Tabellenname der Junction) oder fixed (der deklarierte Alias). Alle werden in Upper-Snake-Case umgewandelt |
Junction-gestützte Beziehungen¶
Eine assoziative Tabelle kann als erstklassige Cypher-Beziehung statt als Knoten deklariert werden, sodass ihre eigenen Spalten zu den Attributen dieser Beziehung werden: (REQ-1586)
relationships:
- id: pets-bonded-pair
source_table_id: pets
target_table_id: pets
source_column: id
target_column: id
cardinality: one-to-many
via_table: pet_companions
via_source_column: pet_id
via_target_column: companion_pet_id
via_type_column: relation_type
via_type_value: bonded pair
via_label_source: column
Die Junction ist eine registrierte Tabelle wie jede andere und muss registriert sein, bevor eine Beziehung sie
benennen kann. Deklarieren Sie sie einmal pro Diskriminatorwert: Drei Zeilen über pet_companions erzeugen
BONDED_PAIR, LITTERMATE und SHARES_ENCLOSURE als drei unterschiedliche Cypher-Typen, jeder mit den
verbleibenden Spalten der Junction-Zeile als Kanteneigenschaften. Die mitgelieferte Demo-Konfiguration
deklariert genau dies.
Eine Junction-Kante ist eine Cypher-Beziehung, kein GraphQL-Join-Feld: Der GraphQL-Join-Emitter baut
seine ON-Klausel für ein einzelnes Spaltenpaar und hat keinen Platz für den zweiten Hop, sodass Junction-Kanten
von der generierten SDL und von pg_constraint ausgeschlossen sind. [tool-verified: provisa/compiler/schema_gen.py:304]
Die Junction-Tabelle bleibt als eigenes Root-Feld abfragbar und wird aus der Knotenseite des
Cypher-Graph-Schemas entfernt, sodass sie nie als Knotenbezeichnung erscheint.
materialize: true funktioniert auf einer Junction-Kante, und was sie materialisiert, ist die Traversierung statt
eines direkten pets-zu-pets-Joins: Die Sicht hält den Quell-Hop, den Junction-Hop, den Diskriminator
und die eigenen Spalten der Junction neben denen des Ziels. Da die Junction ein drittes Bein des Joins ist,
wird beurteilt, ob die Kante quellenübergreifend ist, über alle drei Tabellen hinweg — eine Junction in einer anderen Quelle
als die beiden, die sie verbindet, wird materialisiert, selbst wenn diese beiden übereinstimmen. Eine Deklaration materialisiert einen
Kantentyp, sodass eine für bonded pair gebaute Sicht nie eine littermate-Traversierung beantwortet.
Kardinalitätswerte [tool-verified: provisa/core/models.py Cardinality enum, lines 79–81]:
many-to-one— jede Quellzeile bildet auf eine Zielzeile ab (FK auf PK)one-to-many— jede Quellzeile bildet auf mehrere Zielzeilen ab (Umkehrung des Obigen)
Sicherheit-auf-Zeilenebene-Regeln¶
RLS-Regeln injizieren WHERE-Klauseln zur Abfragezeit, bezogen auf eine Rolle und optional auf eine Tabelle oder Domäne. [tool-verified: provisa/core/models.py RLSRule class lines 391–395; config/provisa.yaml lines 128–131] (REQ-041)
rls_rules:
- table_id: orders # applies to orders table only
role_id: analyst
filter: "region = current_setting('provisa.user_region')"
- domain_id: sales-analytics # applies to every table in domain (REQ-402)
role_id: analyst
filter: "tenant_id = current_setting('provisa.tenant_id')"
Existieren sowohl eine Regel auf Domänenebene als auch auf Tabellenebene für dieselbe Rolle, hat die Regel auf Tabellenebene Vorrang (REQ-403).
| Feld | Erforderlich | Beschreibung |
|---|---|---|
table_id |
Bedingt | Tabelle, auf die die Regel angewendet wird; schließt sich mit domain_id gegenseitig aus |
domain_id |
Bedingt | Domäne, auf die die Regel angewendet wird; gilt für alle Tabellen in der Domäne (REQ-402) |
role_id |
Ja | Rolle, für die diese Regel gilt |
filter |
Ja | SQL-Prädikat, injiziert in WHERE; kann Session-Variablen referenzieren (REQ-041) |
Funktionen und Webhooks¶
DB-Funktionen¶
Tracken Sie eine Datenbankfunktion und legen Sie sie als GraphQL-Abfrage oder -Mutation offen. [tool-verified: provisa/core/models.py Function class lines 423–438; config/provisa.yaml lines 152–164] (REQ-205)
Datenbankquellen können ihre gespeicherten Prozeduren und Funktionen auch automatisch aus dem Vendor-Katalog erkennen (pg_proc, information_schema.routines, oder Vendor-Äquivalente), wodurch die manuelle Registrierung jeder einzelnen entfällt. Discovery liest prokind und provolatile: unveränderliche/stabile Funktionen registrieren sich als parametrisierte Relationen (Prozedurargumente werden zu Abfrageparametern, dieselbe Form wie OpenAPI-GET-Tabellen), und volatile Prozeduren registrieren sich als Mutations/getrackte Funktionen. Erkannte Routinen durchlaufen die Stage-2-Governance identisch zu handregistrierten. [tool-verified: provisa/api/admin/introspect.py:541, provisa/api/admin/introspect.py:593] (REQ-887)
functions:
- name: get_customers_by_region
source_id: sales-pg
schema: public
function_name: get_customers_by_region
returns: customers
domain_id: sales-analytics
description: "Returns customers filtered by region"
visible_to: [admin, analyst]
kind: query
arguments:
- name: p_region
type: String
| Feld | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
name |
Ja | — | GraphQL-Feldname |
source_id |
Ja | — | Quelle, die die Funktion enthält |
schema |
Nein | public |
Datenbankschema |
function_name |
Ja | — | Tatsächlicher Datenbankfunktionsname |
returns |
Ja | — | Registrierte Tabellen-ID, die die Funktion zurückgibt (REQ-207) |
arguments |
Nein | [] |
Liste von {name, type}-Argumentdefinitionen (REQ-211) |
visible_to |
Nein | [] |
Rollen, die diese Funktion aufrufen können |
writable_by |
Nein | [] |
Rollen, die dies als Mutation aufrufen können |
domain_id |
Nein | "" |
Domäne, zu der diese Funktion gehört |
description |
Nein | null |
GraphQL-Feldbeschreibung |
kind |
Nein | mutation |
"query" oder "mutation" (REQ-205) |
Webhooks¶
Legen Sie einen externen HTTP-Endpunkt als GraphQL-Abfrage oder -Mutation offen. [tool-verified: provisa/core/models.py Webhook class lines 441–455; config/provisa.yaml lines 166–178] (REQ-209)
webhooks:
- name: notify_support
url: http://localhost:9999/notify
method: POST
timeout_ms: 3000
domain_id: sales-analytics
description: "Send a support notification"
visible_to: [admin]
kind: mutation
arguments:
- name: message
type: String
| Feld | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
name |
Ja | — | GraphQL-Feldname |
url |
Ja | — | Webhook-Endpunkt-URL |
method |
Nein | POST |
HTTP-Methode |
timeout_ms |
Nein | 5000 |
Anfrage-Timeout in Millisekunden |
returns |
Nein | null |
Registrierte Tabellen-ID, oder null für Inline-Typ |
inline_return_type |
Nein | [] |
Liste von {name, type}-Feldern für benutzerdefinierte Rückgabeformen (REQ-210) |
arguments |
Nein | [] |
Liste von {name, type}-Argumentdefinitionen |
visible_to |
Nein | [] |
Rollen, die diesen Webhook aufrufen können |
domain_id |
Nein | "" |
Domäne, zu der dieser Webhook gehört |
description |
Nein | null |
GraphQL-Feldbeschreibung |
kind |
Nein | mutation |
"query" oder "mutation" |
Authentifizierung¶
Auth wird unter dem Key auth konfiguriert. [tool-verified: provisa/core/models.py AuthConfig class lines 467–477] (REQ-120)
| Provider | Beschreibung |
|---|---|
none |
Keine Authentifizierung; alle Anfragen werden als default_role behandelt |
firebase |
Firebase Authentication; erfordert project_id und service_account_key (REQ-121) |
keycloak |
Keycloak OIDC (REQ-122) |
oauth |
Generisches OAuth 2.0 (REQ-123) |
simple |
Benutzername/Passwort ohne externen Provider (REQ-124) |
auth:
provider: firebase
assignments_source: provisa # "claims" or "provisa"
default_role: analyst
default_assignments:
- role_id: analyst
domain_id: "*"
firebase:
project_id: ${env:FIREBASE_PROJECT_ID}
service_account_key: ${env:FIREBASE_SERVICE_ACCOUNT_KEY}
assignments_source: claims liest Rollenzuweisungen aus JWT-Claims. assignments_source: provisa liest sie aus Provisas eigenem Zuweisungs-Store. [tool-verified: provisa/core/models.py line 476] (REQ-551)
Ausführungs-Routing¶
Direkte Ausführung — Einzelquellen-RDBMS-Abfragen routen zum nativen Treiber für Latenz unter 100 ms (REQ-027). Quellen benötigen sowohl einen SOURCE_TO_DIALECT-Eintrag als auch einen SOURCE_TO_CONNECTOR-Eintrag, um diesen Pfad zu unterstützen (REQ-229).
Föderierte Ausführung — Mehrquellen-Abfragen und Quellen ohne direkten Treiber routen über die Federation-Engine (REQ-028). Provisa enthält eine eingebettete Federation-Engine; verweisen Sie für großangelegte Deployments auf Ihren eigenen kompatiblen Cluster (REQ-226).
Statistiken — Bei der Registrierung führt Provisa ANALYZE gegen jede veröffentlichte Tabelle aus, um den kostenbasierten Optimizer zu initialisieren (Zeilenanzahlen, Null-Anteil, eindeutige Werte, Min/Max). Fehler werden protokolliert und blockieren die Registrierung nicht (REQ-275).
Graph- & Semantic-Quellen¶
Neo4j¶
Registrieren Sie eine Neo4j-Graphdatenbank als abfragbare Quelle. Stewards verfassen Cypher-Abfragen, die skalare Werte projizieren; Provisa cacht Ergebnisse und legt sie als GraphQL-Typen offen (REQ-295).
Cypher-Abfragen müssen Property-Zugriffe in der RETURN-Klausel verwenden (RETURN n.id AS id, n.name AS name) — die Rückgabe von Knotenobjekten wird bei der Registrierung abgelehnt (REQ-296).
Konfigurationsdatei-Registrierung (REQ-1668)¶
Deklarieren Sie eine neo4j-Quelle und ihre Tabellen in YAML. Jede Tabelle benötigt ein query_template (das Cypher, das ihre Zeilen erzeugt) und typisierte Spalten. Der Key query_template ist unter jedem anderen Quelltyp ungültig. [tool-verified: provisa/core/config_loader.py:456-511]
Eine Quelle benötigt host, port und database. [tool-verified: provisa/core/config_loader.py:456-468] Zeilen werden abgerufen, indem {"statements": [{"statement": <cypher>}]} an /db/<database>/tx/commit gePOSTet wird (die Neo4j-HTTP-Transaktions-API). Eine Antwort mit nicht-leerer errors-Liste wird als fehlgeschlagene Abfrage behandelt, nicht als leeres Ergebnis. [tool-verified: provisa/neo4j/source.py:71-82, provisa/api_source/caller.py:344-347, provisa/api_source/normalizers.py:49-74]
Jede Spalte benötigt data_type. Der Loader bildet Konfigurationstypen auf den zur Abfragezeit verwendeten API-Spaltentyp ab [tool-verified: provisa/neo4j/persist.py:31-64]:
Konfigurations-data_type |
API-Typ |
|---|---|
varchar, text, string, char |
string |
integer, int, bigint, smallint |
integer |
float, double, real, decimal, numeric, number |
number |
boolean, bool |
boolean |
json, jsonb |
jsonb |
varchar(N) und decimal(10,2) werden akzeptiert — der Basistyp vor der Klammer wird verwendet.
Die Registrierung persistiert eine api_sources-Zeile und eine api_endpoints-Zeile pro Tabelle, sodass die Tabellen einen Neustart überstehen, ohne die Datei erneut zu lesen. Die Admin-REST-Endpunkte unter /admin/sources/neo4j schreiben dieselben Zeilen. [tool-verified: provisa/neo4j/persist.py:77-120]
sources:
- id: graph
type: neo4j
host: neo4j
port: 7474
database: neo4j
cache_ttl: 300
tables:
- source_id: graph
schema: neo4j
table: person_skills
query_template: >-
MATCH (p:Person)-[:HAS_SKILL]->(s:Skill)
RETURN p.name AS name, s.skill AS skill, p.experience AS years
columns:
- name: name
data_type: varchar
- name: skill
data_type: varchar
- name: years
data_type: integer
Register Table in der UI (REQ-1670)¶
Eine neo4j-Quelle hat keine Tabellen zum Auflisten, daher fragt das Register-Table-Formular nach der Tabelle, statt eine anzubieten. [tool-verified: provisa-ui/src/pages/tables/RegisterTableForm.tsx (isNeo4j)]
- Wählen Sie die neo4j-Quelle und eine Domäne. Die Schema- und Tabellenauswahl, die Discover-Checkbox und die Watermark-Auswahl erscheinen nicht; die Quelle wird nie introspiziert.
- Geben Sie einen Tabellennamen und das Cypher ein. Das Cypher muss Skalare projizieren (
RETURN a.name AS name); eine Projektion, die einen Knoten oder eine Liste zurückgibt, wird als Fehler gemeldet. - Drücken Sie Preview. Das Formular führt das Cypher mit
LIMIT 5über dieneo4jPreview-GraphQL-Abfrage aus und befüllt die Spaltenliste aus den zurückkommenden Zeilen, typisiert alstext,integer,double,booleanoderjson. [tool-verified:provisa/api/admin/_neo4j_registration.pypreview_neo4j] Eine fehlgeschlagene Vorschau lässt das Cypher im Editor und zeigt die Meldung. - Passen Sie Sichtbarkeit, Aliase oder Maskierung wie bei jeder Tabelle an und registrieren Sie dann. Das Formular verweigert das Absenden, bis eine Vorschau die Spalten typisiert hat, und der Server lehnt eine neo4j-Tabelle ohne Cypher ab (
schema.neo4j_query_required). [tool-verified:provisa/api/admin/schema_mutation_ops.pypersist_neo4j_registration]
Das Cypher wird mit der Tabelle als queryTemplate gespeichert, erscheint in der Lese-Ansicht der Tabelle und persistiert genau wie eine Konfigurationsdatei-Registrierung: eine api_sources-Zeile und eine api_endpoints-Zeile, die der nächste Start hydriert. Das Bearbeiten der Tabelle persistiert ein bearbeitetes Cypher erneut.
Admin-REST-Registrierung¶
# Register via admin API (no YAML config required)
POST /admin/sources/neo4j
{
"source_id": "graph",
"host": "neo4j",
"port": 7474,
"database": "neo4j"
}
# Register a table (preview + validate before persisting)
POST /admin/sources/neo4j/graph/tables
{
"table_name": "person_skills",
"cypher": "MATCH (p:Person)-[:HAS_SKILL]->(s:Skill) RETURN p.name AS name, s.skill AS skill, p.experience AS years",
"ttl": 300
}
Der Preview-Endpunkt (POST /admin/sources/neo4j/{id}/preview) gibt Beispielzeilen zurück und blockiert die Registrierung, wenn das Cypher Knotenobjekte zurückgibt (REQ-296).
SPARQL¶
Registrieren Sie jeden SPARQL-1.1-konformen Triple-Store (Apache Jena Fuseki, Virtuoso, Stardog usw.) als abfragbare Quelle (REQ-297).
Abfragen müssen SELECT-Abfragen sein. Variablennamen in der SELECT-Klausel werden automatisch zu Spaltennamen (REQ-297).
# Register via admin API
POST /admin/sources/sparql
{
"source_id": "knowledge-graph",
"endpoint_url": "http://fuseki:3030/ds/sparql",
"default_graph_uri": "http://example.org/graph"
}
# Register a table (executes LIMIT 5 probe to validate and infer columns)
POST /admin/sources/sparql/knowledge-graph/tables
{
"table_name": "product_categories",
"sparql_query": "SELECT ?product ?label ?category WHERE { ?product a :Product ; rdfs:label ?label ; :hasCategory ?category . }",
"ttl": 600
}
Beide Connectors verwenden die API-Source-Cache-Pipeline — Ergebnisse werden in PostgreSQL mit konfigurierbarer TTL gespeichert, wodurch sie für quellenübergreifende föderierte JOINs verfügbar werden (REQ-295, REQ-297, REQ-299).
Konfigurationsdatei- und UI-Registrierung (REQ-1683)¶
Der host einer sparql-Quelle ist ihre SPARQL-Endpunkt-URL (das Sources-Formular speichert es auf dieselbe Weise). Jede Tabelle darunter trägt query_template, ein SELECT, dessen Variablen die Spalten sind; jede Bindung ist text. [tool-verified: provisa/core/config_loader.py _validate_neo4j_sources, _handle_sparql_table]
sources:
- id: sparql-demo
type: sparql
host: http://localhost:23030/provisa/query
tables:
- source_id: sparql-demo
domain_id: shelter
schema: sparql
table: volunteer
query_template: >-
PREFIX s: <http://provisa.dev/shelter#>
SELECT ?volunteer_id ?name WHERE { ?v a s:Volunteer ; s:id ?volunteer_id ; s:name ?name }
columns:
- { name: volunteer_id, data_type: text, visible_to: [org_admin] }
- { name: name, data_type: text, visible_to: [org_admin] }
Register Table funktioniert genauso wie bei Neo4j: Wählen Sie die Quelle, geben Sie einen Tabellennamen und das SELECT ein, drücken Sie Preview (die sparqlPreview-Abfrage führt es mit LIMIT 5 aus und befüllt die Spaltenliste), dann registrieren. Die Registrierung persistiert eine api_sources-Zeile und eine api_endpoints-Zeile (formularkodiertes POST an den Endpunktpfad, sparql_bindings-Normalisierer), dieselben Zeilen, die eine Konfigurationsdatei-Registrierung schreibt, und die native Engine landet die Zeilen über dieselbe Fetch-Kette wie Neo4j. [tool-verified: provisa/api/admin/_query_api_registration.py, provisa/sparql/persist.py]
Verbindungsbeispiele¶
PostgreSQL¶
- id: sales-pg
type: postgresql
host: postgres
port: 5432
database: provisa
username: provisa
password: ${env:PG_PASSWORD}
Snowflake¶
- id: analytics-sf
type: snowflake
host: org.snowflakecomputing.com
port: 443
database: ANALYTICS
username: svc_provisa
password: ${env:SNOWFLAKE_PASSWORD}
federation_hints:
account: myorg-myaccount
warehouse: COMPUTE_WH
Databricks¶
- id: lakehouse-db
type: databricks
host: my-workspace.azuredatabricks.net
password: ${env:DATABRICKS_TOKEN}
federation_hints:
http_path: /sql/1.0/warehouses/xxxx
MongoDB¶
- id: reviews-mongo
type: mongodb
host: mongodb
port: 27017
database: provisa
username: ""
password: ""
Quellenübergreifende Abfrage¶
{
orders(where: {region: {eq: "us"}}) {
id
amount
customers { # PostgreSQL
name
email
}
productReviews { # MongoDB (federated)
rating
comment
}
}
}
Einzelquellen-Anteile routen direkt (REQ-027). Quellenübergreifende JOINs föderieren mit automatischer Typkonvertierung (REQ-028, REQ-552).