Der MetaJdbc Treiber ermöglicht das Lesen von Meta-Daten (Facebook Graph API, Instagram Business und Meta Ads) über JDBC mit SQL.
Es gelten folgende Konventionen:
jdbc:meta: verwendetjdbc:meta:https://graph.facebook.com/v25.0)public verwendet (Standard)fbk_page_insights_daily, meta_ad_account)/me/accountsmeta_ad_stats, meta_conversion_stats)jdbc:meta:https://graph.facebook.com/v25.0
Der Teil nach jdbc:meta: ist die Graph-API-Basis-URL inklusive API-Version. Sie hat Vorrang vor api.baseUrl in der Spec.
Properties props = new Properties();
props.setProperty("token", "EAAx...");
props.setProperty("spec", "/opt/datasqill/config/meta-spec.json");
Connection conn = DriverManager.getConnection(
"jdbc:meta:https://graph.facebook.com/v25.0", props);
Zeitraum und Objektauswahl gehören ins SQL (FILTER), nicht in die Connection — siehe FILTER.
| Property | Beschreibung | Erforderlich |
|---|---|---|
token |
System-User-Access-Token (Facebook Login for Business) | Ja |
spec |
Pfad zur Spec-Datei (.json, .yaml, .yml, .ini; Dateisystem oder classpath:...) |
Nein (Default: eingebaute Spec) |
von_dt |
Beginn des Zeitraums (yyyy-MM-dd) |
Per FILTER im SQL (Fallback: Connection Property) |
bis_dt |
Ende des Zeitraums (yyyy-MM-dd) |
Per FILTER im SQL (Fallback: Connection Property) |
load_type |
delta (Standard) oder full für async Ad Insights |
Per FILTER oder Connection Property |
stdoutlog |
Debug-Ausgabe: meta, http, rows, cursor oder all (kombinierbar mit +) |
Nein |
Property-Namen sind case-insensitive. config ist ein Alias für spec.
Spec-Pfad:
/opt/datasqill/config/meta-spec.json
/opt/datasqill/config/meta-spec.yaml
classpath:de/softquadrat/jdbc/meta/meta-spec.json
Im keyfile werden nur statische Verbindungsdaten gesetzt (token, spec). Der Ladezeitraum steht im SQL:
jdbc:meta:https://graph.facebook.com/v25.0:dboptionlist={token=EAAx...,spec=/opt/datasqill/meta-spec.json}:
Es wird ein System-User-Token verwendet. Der Treiber:
GET /me/accounts auf und erhält Page-Access-Tokensact_* Ad-Account-AufrufeErforderliche Berechtigungen (Auszug):
pages_read_engagement, pages_show_listinstagram_basic, instagram_manage_insightsads_read (für Paid Media)Pro ETL-Job eine JDBC-Verbindung öffnen und ein SELECT pro Zieltabelle ausführen.
SELECT page_id, name, insta_user_id FROM fbk_page_insights;
SELECT page_id, dat, page_total_media_view_unique
FROM fbk_page_insights_daily
FILTER von_dt='2025-01-01' AND bis_dt='2025-01-31'
;
SELECT ad_account_id, name FROM meta_ad_account;
SELECT ad_account_id, ad_id, impressions, datum
FROM meta_ad_stats
FILTER von_dt='2025-01-01' AND bis_dt='2025-01-31' AND load_type=delta
;
Der Treiber iteriert intern über alle Pages bzw. Ad-Accounts. Mit FILTER können Zeitraum und einzelne Pages eingegrenzt werden. Es gibt kein WHERE und kein LIMIT.
Hinweis: datasqill-SQL unterstützt keine Zeilenkommentare mit --. In meta-staging.sql stehen nur ausführbare Statements.
| Daten | Verhalten |
|---|---|
Page-Liste (/me/accounts) |
einmal pro Verbindung, dann Cache |
| Ad-Account-Liste | einmal pro Verbindung, dann Cache |
| Insights-Daten | bei jedem SELECT neu von der API |
Mehrere SELECTs in derselben Verbindung sparen den erneuten /me/accounts-Aufruf. Derselbe SELECT zweimal führt den kompletten API-Lauf erneut aus.
| Tabelle | Inhalt | von_dt/bis_dt |
|---|---|---|
fbk_page_insights |
Facebook Pages + verknüpfte IG-Accounts | Nein |
fbk_page_insights_daily |
Facebook Page Insights pro Tag | Ja |
ins_page_insights |
Instagram Follower-Snapshot | Nein |
ins_page_insights_daily |
Instagram Account Insights pro Tag | Ja |
ins_media |
Instagram Media-Objekte (Posts/Reels) | Optional (Filter nach Publish-Datum) |
ins_media_insights |
Instagram Media Insights (Lifetime) | Ja (Filter nach Publish-Datum) |
| Tabelle | Inhalt | von_dt/bis_dt |
|---|---|---|
meta_ad_account |
Ad Accounts | Nein |
meta_campaign |
Campaigns (alle Accounts) | Nein |
meta_adset |
Ad Sets | Nein |
meta_ad |
Ads | Nein |
meta_ad_stats |
Ad Performance (async) | Ja (bei load_type=delta) |
meta_conversion_stats |
Conversion Stats (async) | Ja (bei load_type=delta) |
Vollständiges SQL-Beispiel: meta-staging.sql
Die Spec definiert API-Endpunkte, abgefragte Felder/Metriken, Limits und Filter. Format: JSON (empfohlen), YAML oder INI (Legacy).
Vollständige Referenz-Spec: meta-spec.json
Kurzbeispiel YAML: meta-spec-example.yaml
{
"api": {
"version": "v25.0",
"baseUrl": "https://graph.facebook.com"
},
"fbk_page_insights_daily": {
"endpoint": "insights",
"fields": [
"page_total_media_view_unique",
"page_media_view",
"page_post_engagements"
],
"tablename": "stage.fbk_page_insights_daily"
}
}
api:
version: v25.0
baseUrl: https://graph.facebook.com
fbk_page_insights_daily:
endpoint: insights
fields:
- page_total_media_view_unique
- page_post_engagements
Jeder Schlüssel auf Root-Ebene (außer api) ist der Name einer vordefinierten SQL-Tabelle und parametrisiert deren API-Aufrufe (fields, endpoint, limit, …). Neue Tabellennamen lassen sich nicht per Spec hinzufügen.
| Feld | Beschreibung | |
|---|---|---|
endpoint |
Graph-API-Endpunkt relativ zur Page/Ad Account ID | |
endpoints |
Kommagetrennte Endpunkte (nur ad_account, z. B. owned + client accounts) |
|
fields |
Abzufragende Felder oder Insights-Metriken (Array oder CSV-String) | |
limit |
Page-Size für paginierte Requests | |
filtering |
Meta-API-Filtering-Ausdruck (Paid Media) | |
breakdowns |
Breakdowns für async Insights | |
tablename |
Staging-Zielname (Dokumentation) | JDBC ignoriert |
Bei fbk_page_insights_daily, ins_page_insights_daily und ins_media_insights werden die Metrik-Spalten aus fields in der Spec gelesen. Neue Metriken können in der Spec ergänzt werden, ohne den Treiber neu zu kompilieren.
Stammdaten-Spalten (page_id, media_id, ad_account_id, …) bleiben im Treiber fest definiert.
Die Graph API hat pro Datentyp unterschiedliche Lademuster (Page-Iteration, Async-Jobs, Media-Pagination, Pivot-Logik), die im Treiber als feste Fetch-Strategien implementiert sind.
| Konfiguration | Spec | Treiber (Java) |
|---|---|---|
| SQL-Tabellenname | Nein | Ja — 12 feste Namen |
| Fetch-Strategie (wie geladen wird) | Nein | Ja — z. B. Page Insights Daily, Async Ad Stats |
Stammdaten-Spalten (page_id, ad_account_id, …) |
Nein | Ja |
Metrik-Spalten (fields) |
Ja | Basis-Spalten + Spec |
| API-Endpunkte, Limits, Filter, Breakdowns | Ja | — |
tablename (Staging-Ziel) |
Ja | JDBC ignoriert |
Praktische Folgen:
Jeder Spec-Abschnitt (z. B. fbk_page_insights_daily) ist an genau eine vordefinierte SQL-Tabelle gekoppelt. Der Abschnittsname muss dem Tabellennamen entsprechen.
SELECT page_id, name, insta_user_id
FROM fbk_page_insights
;
SELECT page_id, dat, page_total_media_view_unique, page_post_engagements
FROM fbk_page_insights_daily
FILTER von_dt='2025-01-01' AND bis_dt='2025-01-31'
;
SELECT page_id, dat, page_total_media_view_unique
FROM fbk_page_insights_daily
FILTER von_dt='2025-01-01' AND bis_dt='2025-01-31' AND page_id='330419580652874'
;
In datasqill-SQL heißt die Klausel FILTER (nicht WHERE). Sie steuert API-Parameter des Treibers — vor allem den Ladezeitraum und optional einzelne Pages.
Syntax: param=value, mehrere Parameter mit AND verknüpft. Werte in einfachen Anführungszeichen oder unquoted.
| FILTER-Parameter | Alias | Wirkung |
|---|---|---|
von_dt |
from_date |
Beginn des Zeitraums (yyyy-MM-dd) |
bis_dt |
to_date |
Ende des Zeitraums (yyyy-MM-dd) |
page_id |
— | Nur diese Facebook-Page laden |
insta_user_id |
— | Nur diesen Instagram-Account laden |
load_type |
— | delta oder full für async Ad Insights |
Priorität: FILTER-Werte überschreiben Connection Properties. In datasqill-ETL-Jobs den Zeitraum immer im SQL setzen — Connection/keyfile pflegt nur der Administrator (token, spec).
Beispiele:
SELECT ad_id, impressions, date_start
FROM meta_ad_stats
FILTER von_dt='2025-01-01' AND bis_dt='2025-01-31' AND load_type=delta
;
SELECT insta_user_id, dat, reach
FROM ins_page_insights_daily
FILTER from_date='2025-01-01' AND to_date='2025-01-31' AND insta_user_id='17841400000'
;
INSERT, UPDATE, DELETEWHERE, ORDER BY-- …)COLUMNS-KlauselSpaltenauswahl per SELECT funktioniert — es werden nur die referenzierten Spalten zurückgegeben.
Spaltennamen, die SQL-Schlüsselwörter sind, müssen in doppelten Anführungszeichen stehen:
SELECT insta_user_id, media_id, "timestamp", permalink FROM ins_media;
Betrifft u. a. timestamp in ins_media und ins_media_insights.
follower_count (Daily)Die Metrik follower_count in ins_page_insights_daily kann bei der Graph API nur für die letzten 30 Tage (ohne heute) abgefragt werden. Für ältere Tage im FILTER-Zeitraum liefert der Treiber die übrigen Metriken (reach, likes, …) und setzt follower_count auf NULL — ohne API-Fehler.
Über das Schema system stehen virtuelle Tabellen zur Verfügung:
| Tabelle | Inhalt |
|---|---|
table_list |
Alle registrierten Meta-Tabellen |
column_list |
Spalten (inkl. dynamischer Metriken aus der Spec) |
pk_list |
Primärschlüssel |
SELECT table_name, remarks
FROM system.table_list
WHERE table_name LIKE 'meta_%'
;
SELECT column_name, type_name
FROM system.column_list
WHERE table_name = 'fbk_page_insights_daily'
;
token → GET /me/accounts → alle Pages
├─ fbk_page_insights → Page-Stammdaten
├─ fbk_page_insights_daily → GET /{page-id}/insights (pro Page)
├─ ins_page_insights → GET /{ig-user-id}
├─ ins_page_insights_daily → GET /{ig-user-id}/insights (pro Tag)
├─ ins_media → GET /{ig-user-id}/media
└─ ins_media_insights → GET /{media-id}/insights (pro Media)
token → Ad Accounts (owned + client)
├─ meta_ad_account → Stammdaten
├─ meta_campaign/adset/ad → paginierte Entity-Calls pro Account
└─ meta_ad_stats → POST async insights → poll → GET results
stdoutlog=meta+http+rows
| Level | Ausgabe |
|---|---|
meta |
API-Aufrufe, Page-/Account-Auflösung, übersprungene Metriken |
http |
HTTP-Methode und URL |
rows |
Gelesene Zeilen pro Batch |
cursor |
Geöffnete Tabelle |
Typische Fehler:
| Meldung | Ursache / Lösung |
|---|---|
(#100) The value must be a valid insights metric |
Metrik in Graph API v25 deprecated — aus Spec entfernen oder Treiber überspringt sie einzeln |
Missing connection property "von_dt" |
FILTER von_dt='…' AND bis_dt='…' ergänzen (Pflicht bei Daily-/Delta-Tabellen) |
Sorry, I cannot understand -- … |
Keine ---Kommentare in datasqill-SQL — Kommentarzeile entfernen |
mismatched input 'timestamp' |
Spalte "timestamp" in doppelten Anführungszeichen quoten |
follower_count … last 30 days |
Historische Tage: Treiber überspringt follower_count automatisch; neuen Build nutzen |
HTTP 429 |
Rate Limit — Treiber retried automatisch; Last reduzieren |
| Lange Laufzeit ohne Ausgabe | Normal bei vielen Pages/Media — stdoutlog aktivieren |
Meta depreciert regelmäßig Insights-Metriken (z. B. page_impressions_unique in v25). Die Default-Spec nutzt aktuelle Metriken (page_total_media_view_unique, page_media_view). Bei API-Fehlern die Meta Insights-Dokumentation prüfen.
ins_media_insights führt einen API-Call pro Media-Objekt aus. Bei vielen Posts kann ein Load deutlich dauern.
Ungültige Metriken pro media_type (FEED, REELS, STORY) werden automatisch übersprungen.