Quelltypen¶
Ausführungsmodell¶
Letztlich läuft jede Abfrage durch die Föderations-Engine, die Föderation über alle Quellen 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 Föderation | Nein | Ja | Redshift, Druid, Exasol, Hive, Iceberg, Delta Lake, Hive (S3-basiert) |
| Direktlesend (Replika) | Ja | Ja | Snowflake, Databricks, ClickHouse — Treiber liest Daten und legt eine Replika an; Abfragen laufen gegen die Replika in der aktiven Engine |
| Materialisieren → Föderation | Nein | Nein | REST/OpenAPI, entferntes 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 die Föderations-Engine (REQ-027, REQ-229). Sie behalten vollständige Connector-Unterstützung und nehmen an der Föderation teil, wenn sie mit anderen Quellen gejoint werden (REQ-028).
Nur-Föderations-Quellen werden immer durch die Föderationsschicht abgefragt. Es existiert kein direkter Treiber (REQ-229).
Direktlesende (Replika)-Quellen haben einen DirectDriver, der nativ aus dem Warehouse liest (wo verfügbar Arrow-nativ), eine Replika im Materialisierungsspeicher der aktiven Engine anlegt, und anschließend laufen Abfragen gegen diese Replika. Siehe Warehouses als benannte Quellen.
Materialisieren-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 quellübergreifende Abfragen durch die Föderations-Engine erreichbar werden (REQ-309).
Alle Quellen¶
Referenz für jeden von Provisa unterstützten Quelltyp. „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 genutzt wird, wenn die Quelle an quellübergreifenden 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 | Mutationen |
|---|---|---|---|---|
postgresql |
asyncpg | postgresql | postgres | Ja |
mysql |
aiomysql | mysql | mysql | Ja |
mariadb |
aiomysql | mariadb | mysql | Ja |
singlestore |
— | singlestore | singlestore | Föderiert |
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 |
Wire-kompatible Datenbanken nutzen den JDBC-Treiber, nativen asynchronen Treiber und 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 über DuckDB-Community-Extensions in place 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 | Mutationen | Anmerkungen |
|---|---|---|---|---|---|
snowflake |
SnowflakeDriver | snowflake | snowflake | Föderiert | Liest via snowflake-connector-python; legt Replika an; account/warehouse/role in federation_hints (REQ-988) |
bigquery |
— | bigquery | bigquery | Föderiert | Kein DirectDriver; erreicht über Föderations-Engine oder BigQuery-Engine-ATTACH |
databricks |
DatabricksDriver | delta_lake | databricks | Föderiert | Liest via databricks-sql-connector (Cloud Fetch, Arrow); legt Replika an; http_path erforderlich in federation_hints (REQ-987) |
redshift |
— | redshift | redshift | Föderiert | — |
fabric |
MssqlWarehouseDriver | — | tsql | Föderiert | Microsoft Fabric Warehouse; T-SQL über TDS, Azure-AD-Auth; legt Replika an (REQ-995) |
synapse |
MssqlWarehouseDriver | — | tsql | Föderiert | Azure Synapse SQL; T-SQL über TDS, Azure-AD-Auth; legt Replika an (REQ-995) |
trino |
SQLAlchemyDriver | — | — | Föderiert | Entfernter Trino/Presto-Koordinator, gelesen über den SQLAlchemy-Trino-Dialekt; legt Replika auf jeder Engine an (REQ-994) |
Analytics / OLAP¶
[tool-verified: executor/drivers/clickhouse.py]
| Quelltyp | Direkter Treiber | Connector-Name | Dialekt | Mutationen | Anmerkungen |
|---|---|---|---|---|---|
clickhouse |
ClickHouseDriver | clickhouse | clickhouse | Föderiert | Liest via clickhouse-connect (HTTP); secure: "true" in federation_hints für TLS (REQ-986) |
druid |
— | druid | druid | Nein | — |
exasol |
— | exasol | exasol | Nein | — |
elasticsearch |
— | elasticsearch | — | Nein | Connector-Eigenschaften stammen aus der Mapping-DSL des Typs [tool-verified: trino_connectors.py:309] |
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 reine Föderationsquellen — kein direkter Treiber, kein Dialekt. [tool-verified: LAKE_ONLY_SOURCES in provisa/core/source_registry.py] (REQ-229)
| Quelltyp | Connector-Name | Time Travel | Anmerkungen |
|---|---|---|---|
iceberg |
iceberg | Ja (as_of-Argument, REQ-372) |
— |
delta_lake |
delta_lake | Ja (as_of-Argument, REQ-372) |
— |
hive |
hive | Nein | — |
hive_s3 |
hive | Nein | S3-basiertes 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 | Mutationen |
|---|---|---|
mongodb |
mongodb | Nein |
cassandra |
cassandra | Nein |
redis |
redis | Nein |
Streaming¶
| Quelltyp | Mechanismus | Mutationen |
|---|---|---|
kafka |
Föderierter Kafka-Connector; Schema via Confluent Schema Registry (Avro, Protobuf, JSON Schema), manuelle Definition oder Sample-Inferenz (REQ-147, REQ-150) | Nur Sink (REQ-176) |
websocket |
Externer WebSocket-Feed — verbinden, abonnieren, Events 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 | Mutationen |
|---|---|---|
ingest |
Externe Dienste senden JSON-Events per POST; Ergebnisse materialisiert (REQ-331, REQ-335) | Nein |
Graph & Semantik¶
| Quelltyp | Mechanismus | Mutationen |
|---|---|---|
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 verweisen mit path auf eine Datei.
| Quelltyp | Transporte | Mutationen |
|---|---|---|
sqlite |
lokal | Ja |
csv |
lokal | Nein |
parquet |
lokal, s3:// |
Nein |
Private Buckets benötigen Anmeldedaten (AWS-Region und Schlüssel aus der Umgebung). Für CSV über s3:// oder http(s)://, oder um viele Dateien auf einmal zu registrieren, verwenden Sie die Quelle files. [tool-verified: provisa/file_source/source.py]
files-Quelle — path verweist auf ein Glob, durchläuft es rekursiv und registriert das Verzeichnis als föderierten Katalog von Tabellen. Es liest viele Formate über viele Transporte; die untenstehenden Mengen stammen vom File-Connector (kenstott/calcite-Fork). [tool-verified: provisa/core/catalog.py files-Zweig und 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 umgewandelte 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
Observability & Sonstige¶
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 | Mutationen |
|---|---|---|
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 materialisiert ihre Zeilen, indem es den mitgelieferten Calcite-pgwire-Server des Connectors startet (pgwire-sharepoint, pgwire-splunk), sich als generischen PostgreSQL-Endpunkt daran verbindet und die Zeilen im Materialisierungsspeicher für die Föderation anlegt (REQ-954). Beide Connectors aktivieren immer Case-insensitive-Namensabgleich, passend zur 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 exponiert (REQ-726, REQ-731). Zwei Auth-Methoden: CLIENT_CREDENTIALS (Standard) und zertifikatsbasiert über ein PFX-Zertifikat (REQ-727). Geheime Werte in mapping werden vor Erreichen des Connectors über die Secrets-Engine aufgelöst (REQ-729). [tool-verified: provisa/federation/trino_connectors.py lines 230–252]
| Quellfeld | Connector-Eigenschaft | Anmerkungen |
|---|---|---|
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, wenn auth_type: CERTIFICATE |
mapping.certificate_password |
certificate-password |
PFX-Passwort |
Wenn der Connector information_schema.columns nicht exponiert, registrieren Sie die Tabelle mit expliziten Spaltendefinitionen (aus der Microsoft-Graph-API bezogen) über die Mutation registerTable (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
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 einem Standardport von 8089 konstruiert (REQ-722). Auth: Wenn mapping.use_token true ist (Standard), wird password als API-Token übergeben; wenn false, werden username und password als separate Anmeldedaten übergeben (REQ-723). [tool-verified: provisa/federation/trino_connectors.py lines 262–286]
| Quellfeld | Connector-Eigenschaft | Anmerkungen |
|---|---|---|
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 beschränken |
mapping.datamodel_filter |
datamodel-filter |
auf ein Datenmodell filtern |
mapping.disable_ssl_validation |
disable-ssl-validation |
für selbstsignierte Zertifikate (REQ-724) |
- 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 exponiert (REQ-309, REQ-318, REQ-327). Gecachte Tabellen nehmen wie jede andere Quelle an föderierten Abfragen teil (REQ-313).
JSONB-Regeln: Komplexe, als JSONB gespeicherte Spalten (Objekte, Arrays) sind nicht filterbar (REQ-119). Der Zugriff auf Unterfelder nutzt ->>-Extraktion in SQL (REQ-151). Beziehungen werden zwischen Tabellen mittels skalarer FK-Spalten deklariert — JSONB-Blob-Spalten sind keine Join-Ziele. Verwenden Sie JSONB-Promotion, um verschachtelte Felder in native Skalarspalten umzuwandeln, wenn Filtern oder Joinen darauf erforderlich ist (REQ-119).
GovData¶
US-amerikanische offene Regierungsdaten. 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 exponiert 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 Kommentar]
| Thema | Exponierte 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 |
Data-Quality-Checker (REQ-1443)¶
Ein Data-Quality-Checker ist ein Quelltyp, kein Subsystem. Seine Scan-Ausgabe ist Daten: Ein Prüfergebnis ist eine Beobachtung, landet also über den gewöhnlichen Quellpfad und erbt Kadenz, Aktualität, Events, Lineage, Governance, RLS, Grid und Export von jeder anderen Quelle. [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 Funktionsfrage.
| Quelltyp | Contract-Dialekt | Extra | Lizenz | Gehostete Cloud-Ebene |
|---|---|---|---|---|
soda |
Soda-Contract-YAML | pip install .[soda] (soda-postgres) |
Elastic License 2.0 | Verweigert — siehe unten |
great_expectations |
Expectation-Suite-JSON | pip install .[gx] (great-expectations[postgresql]) |
Apache 2.0 | Erlaubt |
Die Elastic License 2.0 verbietet es, die Software Dritten als gehosteten oder verwalteten Dienst bereitzustellen, und Soda innerhalb der SaaS-Ebene im Namen eines Mandanten laufen zu lassen ist genau das. config/capabilities.yaml trägt die Trennung als cloud_eligible: false an der soda-Option, und die gehostete Ebene 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 vendort und linkt nichts. Der Scan läuft in einem Child-Interpreter (python -m provisa.dq.worker), der einzige Ort, an dem soda_core oder great_expectations importiert wird, sodass ein source-available Checker nie den Serverprozess erreicht und ein Checker-Crash einen Subprozess statt der Event-Loop tötet. [tool-verified: provisa/dq/runner.py build_command, run_contract]
Die Quelle verweist auf Provisas eigenen pgwire-Endpunkt. Das ermöglicht es einem einzigen Postgres-Treiber, eine Snowflake- oder Iceberg-gestützte Tabelle zu prüfen: Der Checker scannt die föderierte Sicht, nicht das darunterliegende System. Weil Richtlinien auf diese Verbindung angewendet werden, wird die Scan-Identität deklariert statt geerbt — eine gefilterte Zeilenmenge darf niemals eine still bestehende Prüfung 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 Contract, und der Contract ist die gesamte Registrierung. Die Tabelle trägt dq_contract — den Contract-Text wortwörtlich — und sonst nichts über ihre Form. Spalten, Watermark und Promotions sind 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 Contract benennt bereits sein Ziel-Dataset, sodass die Registrierung ihn so parst, wie
extract_inputsSQL parst (REQ-939), und ihn zur regulierten Tabelle auflöst. Eine Definition, keine zweite Kopie, die abdriften kann. Ein Contract, der ein nicht reguliertes Dataset benennt, schlägt laut bei der Registrierung fehl, statt Zeilen zu landen, die niemand angefordert hat. - Spalten. Die Ergebnishülle 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 zur Watermark, was das Landen zu einem Append macht (REQ-982). Scan-Historie akkumuliert ohne separates Historie-Subsystem. - Promotions.
freshness_max_timestampunddataset_rows_testedwerden aus demdiagnostics-jsonb als typisierte Spalten promotet (REQ-119). Weitere hinzuzufügen funktioniert wie bei jeder anderen jsonb-Spalte. [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 über das Fenster hinweg aktuell 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 MV über den gelandeten Ergebnissen. Weil eine gelandete Beobachtung keine Determinismus-Verpflichtung trägt (REQ-964), sind hier nicht-deterministische Prüfungen zulässig, die auf einem Preflight-Gate nie stehen könnten — Anomalie-Score, Trailing-Window-Änderung, Aktualität gegen jetzt.
Der Contract wird in der UI autorisiert, im Data-Quality-Panel der Tabellenbearbeitungsoberfläche, und der rohe Contract-Text dort ist immer die Source of Truth. Ein Dry Run führt den Contract gegen die Live-Tabelle aus und zeigt die Ergebnisse, ohne sie zu landen — so fangen Sie einen Contract ab, dessen Dataset-Name unerwartet aufgelöst wurde und andernfalls nichts als bestehende Zeilen landen würde.
Benutzerdefinierte Connectors (REQ-1177)¶
Die nativen Föderations-Engines — Postgres, DuckDB und ClickHouse — erlangen Erreichbarkeit zu einem neuen Quelltyp, wenn ein Betreiber einen Connector dafür 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 als solche existierte schon vorher. Die Trino-Engine ist auf ihrer eigenen Ebene seit langem erweiterbar — ein generischer JDBC-Connector, parametrisiert pro Quelltyp, ein Katalog-.properties-Body pro Typ, sowie 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 konfigurationsgetriebene Erweiterbarkeit zu den zwei nativen, clusterlosen Engines, die zuvor einen festen Connector-Satz trugen.
Die Konfiguration wird leer ausgeliefert. Eingebaute Connectors decken die Reichweite ab Werk ab; alles in dieser Datei ist vom Betreiber autorisiert. [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).
Descriptor-Arten¶
| Engine | Art | Mechanismus | Was der Descriptor 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=… (exponiert automatisch jede entfernte Tabelle) |
ch_engine, engine_template |
clickhouse |
clickhouse_table |
pro-Tabelle CREATE TABLE ENGINE=… (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-Descriptor liefert nur die Pro-FDW-Varianz — Extension-Name, Server-Options-Schlüssel, User-Mapping-Schlüssel, Import-Flag, Table-Options. 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 Extension, die einen Katalog via ATTACH exponiert, nutzt duckdb_attach; eine, die eine lesende Table-Funktion exponiert, nutzt duckdb_scan. Eine Extension, die zu keinem 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 exponiert (clickhouse_database, z. B. Redis/MySQL), eine Pro-Tabelle-Engine, deren Spalten die Registry liefert (clickhouse_table, z. B. die JDBC/ODBC-Brücke — das engine_template kann einen {table}-Platzhalter tragen, den die Runtime 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 ab Werk 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 Tippfehler im Descriptor darf einen Quelltyp nicht still unerreichbar lassen. [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 verifiziert:
- 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 Extension, 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 Schlüssel aus federation_hints. DuckDB-Attach-Templates erhalten zusätzlich {alias} — den internen Katalog-Alias, den Provisa der angehängten Datenbank zuweist.
Ein Template, das auf ein unbekanntes Feld verweist, schlägt zur Attach-Zeit laut fehl und deckt eine Descriptor-/Quell-Fehlpassung auf, bevor defektes DDL die Engine erreicht.
Beispiele¶
Postgres — MongoDB via 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 via read_xlsx (Scan-Table-Funktion)
- 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]
Mit einem der beiden Descriptors an Ort und Stelle routet die Registrierung einer Quelle mit dem deklarierten source_type durch 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 Föderations-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 legt eine Replika im Materialisierungsspeicher der aktiven Engine an. Die Abfrage läuft dann gegen diese Replika. Dies 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 eine lokale Replika statt bei jeder Anfrage über das Wire zum Warehouse.
Lesevorgänge sind Arrow-nativ, wo das Warehouse dies unterstützt: Databricks nutzt Cloud Fetch, Snowflake nutzt fetch_arrow_table, und ClickHouse nutzt die native Columnar-HTTP-Schnittstelle.
Erweiterte Verbindungsparameter, die die Standardfelder host/port/username/password nicht tragen können, kommen 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, dasselbe Warehouse als Föderations-Engine auszuwählen. Eine Snowflake-Quelle auf einer DuckDB-Engine legt eine Replika in DuckDB an, nicht in Snowflake.
Cloud-Objekt-/Lake-Daten (Parquet-, CSV-, Iceberg-, Delta-Lake-Dateien auf S3 / GCS / R2) sind ein separater Quelltyp, der in place anhängt, wenn die aktive Engine einen ATTACH-Connector für diesen Typ hat. Keine Replika wird angelegt — die Engine scannt den Objektspeicher direkt. Anmeldedaten für diese Quellen kommen 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 sich eine gemeinsame Menge von Feldern. [tool-verified: provisa/core/models.py Source-Klasse, 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; ${env:VAR} für Secret-Auflösung verwenden |
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-Antwort-Caching aktivieren |
cache_ttl |
Nein | null |
Cache-TTL in Sekunden; erbt den globalen Standard, wenn null |
cache_catalog |
Nein | null |
Föderierter Katalog für API-Cache; standardmäßig der eigene Katalog der Quelle |
cache_schema |
Nein | api_cache |
Schema innerhalb des Cache-Katalogs |
naming_convention |
Nein | null |
Globale Namenskonvention für diese Quelle überschreiben (REQ-194) |
federation_hints |
Nein | {} |
Sitzungseigenschaften, die an die Föderations-Engine übergeben werden, 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 gefensterte Abfragen (z. B. 1h) (REQ-148) |
topics[].columns |
Spaltendefinitionen für das Topic-Schema (REQ-150) |
Spaltensichtbarkeit¶
Das Feld visible_to an jeder Spalte ist eine Liste von Rollen-IDs, die diese Spalte sehen können. [tool-verified: provisa/core/models.py Column-Klasse Zeile 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 in der visible_to-Liste einer Rolle fehlen, 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-Klasse 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 hält |
target_table_id |
Ja | Referenzierte Tabelle; leer für berechnete Beziehungen |
source_column |
Ja | Spalte auf der Quelltabelle |
target_column |
Ja | Spalte auf der Zieltabelle; leer für berechnete Beziehungen |
cardinality |
Ja | many-to-one oder one-to-many (REQ-019) |
materialize |
Nein | Automatisch eine materialisierte Sicht für quellübergreifende Joins erzeugen (REQ-158) |
refresh_interval |
Nein | MV-Aktualisierungsintervall in Sekunden (Standard: 300) |
target_function_name |
Nein | DB-Funktionsname für berechnete Beziehungen |
function_arg |
Nein | Welches Funktionsargument den Quellspaltenwert erhält |
alias |
Nein | Menschenlesbarer Beziehungstyp (z. B. WORKS_FOR) |
graphql_alias |
Nein | Benennt das SDL-Feld, das diese Beziehung am übergeordneten Typ exponiert. Wenn abwesend, 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 | Wenn true, diese Beziehung von Cypher-Graph-Kanten ausschließen |
source_json_key |
Nein | Diesen Schlüssel aus der Quellspalte als JSON-Objekt extrahieren, vor dem JOIN |
Kardinalitätswerte [tool-verified: provisa/core/models.py Cardinality-Enum, lines 79–81]:
many-to-one— jede Quellzeile ordnet sich einer Zielzeile zu (FK zu PK)one-to-many— jede Quellzeile ordnet sich mehreren Zielzeilen zu (Umkehrung des obigen)
Regeln für Sicherheit auf Zeilenebene¶
RLS-Regeln injizieren WHERE-Klauseln zur Abfragezeit, geltend für eine Rolle und optional für eine Tabelle oder Domäne. [tool-verified: provisa/core/models.py RLSRule-Klasse 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')"
Wenn sowohl eine domänenweite als auch eine tabellenspezifische Regel für dieselbe Rolle existieren, hat die tabellenspezifische Regel 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 auf Sitzungsvariablen verweisen (REQ-041) |
Funktionen und Webhooks¶
DB-Funktionen¶
Tracken Sie eine Datenbankfunktion und exponieren Sie sie als GraphQL-Query oder -Mutation. [tool-verified: provisa/core/models.py Function-Klasse lines 423–438; config/provisa.yaml lines 152–164] (REQ-205)
Datenbankquellen können auch ihre gespeicherten Prozeduren und Funktionen automatisch aus dem Hersteller-Katalog entdecken (pg_proc, information_schema.routines, oder Hersteller-Äquivalente), wodurch die Notwendigkeit entfällt, jede einzeln von Hand zu registrieren. Discovery liest prokind und provolatile: immutable/stable Funktionen registrieren sich als parametrisierte Relationen (Prozedurargumente werden zu Abfrageparametern, dieselbe Form wie OpenAPI-GET-Tabellen), und volatile Prozeduren registrieren sich als Mutationen/getrackte Funktionen. Entdeckte Routinen durchlaufen die Stage-2-Governance identisch zu von Hand registrierten. [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¶
Exponieren Sie einen externen HTTP-Endpunkt als GraphQL-Query oder -Mutation. [tool-verified: provisa/core/models.py Webhook-Klasse 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 Schlüssel auth konfiguriert. [tool-verified: provisa/core/models.py AuthConfig-Klasse lines 467–477] (REQ-120)
| Provider | Beschreibung |
|---|---|
none |
Keine Authentifizierung; alle Anfragen werden als default_role behandelt |
firebase |
Firebase Authentication; benötigt 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 Zuweisungsspeicher. [tool-verified: provisa/core/models.py line 476] (REQ-551)
Ausführungsrouting¶
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 — Quellübergreifende Abfragen und Quellen ohne direkten Treiber routen durch die Föderations-Engine (REQ-028). Provisa enthält eine eingebettete Föderations-Engine; verweisen Sie für großskalige 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 grundieren (Zeilenanzahlen, Null-Anteil, distinkte Werte, Min/Max). Fehler werden protokolliert und blockieren die Registrierung nicht (REQ-275).
Graph- & Semantik-Quellen¶
Neo4j¶
Registrieren Sie eine Neo4j-Graphdatenbank als abfragbare Quelle. Data Stewards autorisieren Cypher-Abfragen, die skalare Werte projizieren; Provisa cacht Ergebnisse und exponiert sie als GraphQL-Typen (REQ-295).
Cypher-Abfragen müssen Property-Accessoren in der RETURN-Klausel verwenden (RETURN n.id AS id, n.name AS name) — die Rückgabe von Node-Objekten wird zur Registrierungszeit abgelehnt (REQ-296).
# 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 Node-Objekte zurückgibt (REQ-296).
SPARQL¶
Registrieren Sie jeden SPARQL-1.1-konformen Triplestore (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 nutzen die API-Quellen-Cache-Pipeline — Ergebnisse werden in PostgreSQL mit konfigurierbarer TTL gespeichert, wodurch sie für quellübergreifende föderierte JOINs verfügbar sind (REQ-295, REQ-297, REQ-299).
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: ""
Quellübergreifende Abfrage¶
{
orders(where: {region: {eq: "us"}}) {
id
amount
customers { # PostgreSQL
name
email
}
productReviews { # MongoDB (federated)
rating
comment
}
}
}
Einzelquellen-Anteile routen direkt (REQ-027). Quellübergreifende JOINs föderieren mit automatischer Typkonvertierung (REQ-028, REQ-552).