Best Practices für Repositories

In diesem Dokument finden Sie die folgenden Informationen zu Dataform-Repositories:

Best Practices für Repositories in Dataform

In diesem Abschnitt finden Sie einen Überblick über Best Practices für die Verwaltung der Repository-Größe, der Repository-Struktur und des Code-Lebenszyklus in Dataform.

Best Practices für die Größe des Repositories

Die Größe des Repositories wirkt sich auf mehrere Aspekte der Entwicklung in Dataform aus, darunter:

  • Zusammenarbeit
  • Lesbarkeit der Codebasis
  • Entwicklungsabläufe
  • Workflow-Kompilierung
  • Workflowausführung

In Dataform gelten API-Kontingente und Limits für die Kompilierungsressourcen. Bei einer großen Repository-Größe kann es passieren, dass Ihr Repository diese Kontingente und Limits überschreitet. Dies kann dazu führen, dass die Kompilierung und Ausführung Ihres Workflows fehlschlägt.

Um dieses Risiko zu minimieren, empfehlen wir, große Repositories aufzuteilen. Wenn Sie ein großes Repository aufteilen, teilen Sie einen großen Workflow in eine Reihe kleinerer Workflows auf, die sich in verschiedenen Repositories befinden und durch repositoryübergreifende Abhängigkeiten verbunden sind.

So können Sie die Kontingente und Limits von Dataform einhalten, detaillierte Prozesse und Berechtigungen implementieren und die Lesbarkeit und Zusammenarbeit der Codebasis verbessern. Das Verwalten von aufgeteilten Repositories kann jedoch schwieriger sein als das Verwalten eines einzelnen Repositories.

Weitere Informationen zu den Auswirkungen der Repository-Größe in Dataform finden Sie unter Repository-Größe. Weitere Informationen zu Best Practices für das Aufteilen von Repositories finden Sie unter Repositories aufteilen.

Best Practices für die Repository-Struktur

Wir empfehlen, die Dateien im Verzeichnis definitions so zu strukturieren, dass sie die Phasen Ihres Workflows widerspiegeln. Sie können auch eine benutzerdefinierte Struktur verwenden, die Ihren Anforderungen am besten entspricht.

Die folgende empfohlene Struktur von definitions-Unterverzeichnissen spiegelt die wichtigsten Phasen der meisten Workflows wider:

  • sources zum Speichern von Datenquellendeklarationen.
  • intermediate zum Speichern der Datentransformationslogik.
  • output zum Speichern von Definitionen von Ausgabetabellen.
  • extras (optional) zum Speichern zusätzlicher Dateien.

Die Namen aller Dateien in Dataform müssen den Benennungsrichtlinien für BigQuery-Tabellen entsprechen. Wir empfehlen, dass die Dateinamen im definitions-Verzeichnis in einem Dataform-Repository der Unterverzeichnisstruktur entsprechen.

Weitere Informationen zu Best Practices für die Strukturierung und Benennung von Dateien in einem Repository finden Sie unter Code in einem Repository strukturieren.

Best Practices für den Codelebenszyklus

Der Standardcodelebenszyklus in Dataform besteht aus den folgenden Phasen:

Um den Codelebenszyklus in Dataform zu verwalten, können Sie Ausführungsumgebungen wie Entwicklung, Staging und Produktion erstellen.

Weitere Informationen zum Codelebenszyklus in Dataform finden Sie unter Einführung in den Codelebenszyklus in Dataform.

Sie können Ihre Ausführungsumgebungen in einem einzelnen Repository oder in mehreren Repositories speichern.

Ausführungsumgebungen in einem einzigen Repository

Mit Überschreibungen der Arbeitsbereichskompilierung und Releasekonfigurationen können Sie isolierte Ausführungsumgebungen wie Entwicklungs-, Staging- und Produktionsumgebungen in einem einzigen Dataform-Repository erstellen.

Sie haben folgende Möglichkeiten, eine isolierte Ausführungsumgebung zu erstellen:

  • Entwicklungs- und Produktionstabellen nach Schema aufteilen
  • Entwicklungs- und Produktionstabellen nach Schema und Google Cloud Projekt aufteilen.
  • Entwicklungs-, Staging- und Produktionstabellen nach Google Cloud Projekt aufteilen.

Anschließend können Sie mit Workflowkonfigurationen Ausführungen in Staging- und Produktionsumgebungen planen. Wir empfehlen, Ausführungen manuell in der Entwicklungsumgebung auszulösen.

Weitere Informationen zu Best Practices für die Verwaltung des Codelebenszyklus in Dataform finden Sie unter Codelebenszyklus verwalten.

Codelebenszyklus in mehreren Repositories

Wenn Sie die Identity and Access Management-Berechtigungen an jede Phase des Codelebenszyklus anpassen möchten, können Sie mehrere Kopien eines Repositories erstellen und in verschiedenen Google Cloud Projekten speichern.

Jedes Google Cloud Projekt dient als Ausführungsumgebung, die einer Phase des Codelebenszyklus entspricht, z. B. Entwicklung und Produktion.

Bei diesem Ansatz empfehlen wir, die Codebasis des Repositorys in allen Projekten gleich zu halten. Verwenden Sie Überschreibungen der Arbeitsbereichskompilierung, Releasekonfigurationen und Workflowkonfigurationen, um die Kompilierung und Ausführung in jeder Kopie des Repositorys anzupassen.

Repository-Größe – Übersicht

In diesem Abschnitt erfahren Sie, wie sich die Größe des Repositories auf die Workflowentwicklung und die Nutzung von Dataform-Kompilierungsressourcen auswirkt und wie Sie die Nutzung von Kompilierungsressourcen Ihres Repositories schätzen.

Repository-Größe in Dataform

Die Größe eines Repositories wirkt sich auf die folgenden Aspekte der Entwicklung in Dataform aus:

  • Zusammenarbeit Wenn mehrere Mitbearbeiter an einem großen Repository arbeiten, kann das zu einer übermäßigen Anzahl von Pull-Requests führen, was das Risiko von Zusammenführungskonflikten erhöht.

  • Lesbarkeit der Codebasis Eine größere Anzahl von Dateien, die einen Workflow in einem einzelnen Repository bilden, kann die Navigation im Repository erschweren.

  • Entwicklungsprozesse: Für einige Bereiche eines großen Workflows in einem einzelnen Repository sind möglicherweise benutzerdefinierte Berechtigungen oder Prozesse erforderlich, z. B. für die Planung, die sich von den Berechtigungen und Prozessen unterscheiden, die für den Rest des Workflows gelten. Eine große Repository-Größe erschwert es, Entwicklungsabläufe auf bestimmte Bereiche des Workflows anzupassen.

  • Workflow-Kompilierung In Dataform werden Nutzungslimits für Kompilierungsressourcen erzwungen. Ein großes Repository kann dazu führen, dass diese Limits überschritten werden und die Kompilierung fehlschlägt.

  • Workflowausführung Während der Ausführung führt Dataform Repository-Code in Ihrem Arbeitsbereich aus und stellt Assets in BigQuery bereit. Je größer das Repository, desto länger dauert es, bis Dataform es ausgeführt hat.

Wenn sich die große Größe Ihres Repositorys negativ auf Ihre Entwicklung in Dataform auswirkt, können Sie das Repository in mehrere kleinere Repositorys aufteilen.

Limits für Ressourcen zur Repository-Kompilierung

Während der Entwicklung kompiliert Dataform den gesamten Repository-Code in Ihrem Arbeitsbereich, um eine Darstellung des Workflows in Ihrem Repository zu generieren. Dies wird als Kompilierungsergebnis bezeichnet. In Dataform gelten Nutzungslimits für Kompilierungsressourcen.

Die Nutzungslimits Ihres Repositories werden möglicherweise aus den folgenden Gründen überschritten:

  • Ein Fehler mit einer endlosen Schleife im Repository-Code.
  • Ein Speicherleck im Repository-Code.
  • Großes Repository mit etwa mehr als 1.000 Workflow-Aktionen.

Weitere Informationen zu Nutzungslimits für Kompilierungsressourcen finden Sie unter Limits für Dataform-Kompilierungsressourcen.

Ressourcennutzung für die Kompilierung Ihres Repositories schätzen

Sie können die Nutzung der folgenden Kompilierungsressourcen für Ihr Repository schätzen:

  • CPU-Zeitnutzung.
  • Maximale Gesamtgröße der serialisierten Daten des generierten Graphen der Aktionen, die in Ihrem Repository definiert sind.

Um eine grobe Schätzung der aktuellen CPU-Zeitnutzung für die Kompilierung Ihres Repositorys zu erhalten, können Sie die Kompilierung Ihres Dataform-Workflows auf einem lokalen Linux- oder macOS-Computer messen.

  • Wenn Sie die Kompilierung Ihres Workflows messen möchten, führen Sie in Ihrem Repository den Dataform-Befehl dataform compile im folgenden Format aus:

    time dataform compile
    

    Das folgende Codebeispiel zeigt das Ergebnis der Ausführung des Befehls time dataform compile:

    real    0m3.480s
    user    0m1.828s
    sys     0m0.260s
    

Das Ergebnis von real ist ein grober Indikator für die CPU-Zeitnutzung bei der Kompilierung Ihres Repositorys.

Wenn Sie eine grobe Schätzung der Gesamtgröße des generierten Graphen der Aktionen in Ihrem Repository erhalten möchten, können Sie die Ausgabe des Graphen in eine JSON-Datei schreiben. Die Größe der unkomprimierten JSON-Datei ist ein grober Indikator für die Gesamtgröße des Diagramms.

  • Wenn Sie die Ausgabe des kompilierten Graphen Ihres Workflows in eine JSON-Datei in Ihrem Repository schreiben möchten, führen Sie den folgenden Dataform-Befehl in der Befehlszeile aus:

    dataform compile --json > graph.json
    

Repositories aufteilen

In diesem Abschnitt werden Strategien zum Aufteilen eines Dataform-Repositories und zum Verwalten von repositorieübergreifenden Abhängigkeiten erläutert.

Repositories sind die zentralen Einheiten in Dataform. In einem Repository werden alle SQLX- und JavaScript-Dateien gespeichert, aus denen Ihr Workflow besteht, sowie die Dataform-Konfigurationsdateien und ‑Pakete. Sie können einen Workflow in einem einzelnen Repository speichern oder einen Workflow auf mehrere Repositories aufteilen.

Das Aufteilen eines Repositorys in Dataform bietet folgende Vorteile:

  • Beachten Sie die Dataform-Limits für die Nutzung von Kompilierungsressourcen. Wenn Sie einen großen Workflow in mehrere kleinere Repositories aufteilen, verringern Sie das Risiko, die Dataform-Limits für Kompilierungsressourcen zu überschreiten.
  • Detaillierte Prozesse Sie können Prozesse wie CI-Regeln (Continuous Integration) individuell für jedes aufgeteilte Fragment Ihres Workflows und das Entwicklerteam festlegen.
  • Detaillierte Berechtigungen Sie können Berechtigungen für jedes aufgeteilte Fragment Ihres Workflows und das Team, das es entwickelt, individuell festlegen, um die allgemeine Sicherheit des Workflows zu erhöhen.
  • Die Zusammenarbeit wird verbessert, da die Anzahl der Mitbearbeiter, die an jedem geteilten Teil Ihres Workflows arbeiten, minimiert wird.
  • Verbesserung der Lesbarkeit des Codebase Wenn Sie die Dateien eines großen Workflows in mehrere Repositories aufteilen, können Sie jedes Repository einzeln aufrufen, anstatt den gesamten Workflow auf einmal zu bearbeiten.
  • Beschleunigung der Workflowausführung jedes aufgeteilten Fragments des Workflows im Vergleich zur Ausführung des gesamten Workflows.

Das Aufteilen eines Repositories in Dataform hat folgende Nachteile:

  • Benutzerdefinierte CI/CD-Konfiguration (Continuous Integration/Continuous Delivery) für jedes Dataform-Repository und das entsprechende Git-Repository erforderlich.
  • Für jedes Dataform-Repository und das zugehörige Git-Repository ist eine benutzerdefinierte Planungskonfiguration erforderlich.
  • Schwierigkeiten bei der Verwaltung von Abhängigkeiten zwischen den Objekten Ihres Workflows, die sich in mehreren Repositories befinden.
  • Fehlende umfassende DAG-Visualisierung (Directed Acyclic Graph) des SQL-Workflows, der auf mehrere Repositories aufgeteilt ist. In jedem Repository stellt der generierte DAG nur einen Teil des gesamten Workflows dar.

Strategien zum Aufteilen eines Repositorys

Wenn Sie ein Repository aufteilen, teilen Sie die Dateien, aus denen ein übergeordneter SQL-Workflow besteht, in kleinere untergeordnete Workflows auf, die in separaten Dataform-Repositories gespeichert werden.

Sie haben folgende Möglichkeiten, ein Repository aufzuteilen:

  • Ein Repository pro Entwicklungsteam.
  • Ein Repository pro Domain, z. B. Vertrieb, Marketing oder Logistik.
  • Ein zentrales Repository und ein Repository pro Domain, das den Inhalt des zentralen Repositorys als Datenquellen verwendet.

Wenn Sie den übergeordneten Workflow auf einer Git-Hostingplattform eines Drittanbieters hosten möchten, müssen Sie jedes der separaten Repositories mit untergeordneten Workflows einzeln mit einem speziellen Git-Repository eines Drittanbieters verknüpfen.

Abhängigkeiten zwischen Repositories verwalten

Die effizienteste Methode zum Aufteilen eines Repositories besteht darin, den übergeordneten SQL-Workflow in eigenständige untergeordnete Workflows zu unterteilen und so unabhängige Repositories zu erstellen. In einem unabhängigen Repository wird der Inhalt eines anderen Repositorys nicht als Datenquelle verwendet. Bei diesem Ansatz müssen keine repositoryübergreifenden Abhängigkeiten verwaltet werden.

Wenn Sie Repository-übergreifende Abhängigkeiten nicht vermeiden können, können Sie sie verwalten, indem Sie ein Repository in eine Reihe von Repositories aufteilen, in denen ein Repository vom Vorgänger abhängt und eine Datenquelle für den Nachfolger ist. Die Abfolge der Repositories und ihre Abhängigkeiten müssen die Struktur Ihres übergeordneten Workflows am besten widerspiegeln.

Mit Dataform-Datenquellendeklarationen können Sie Abhängigkeiten zwischen Repositories erstellen. Sie können einen BigQuery-Tabellentyp aus einem anderen Dataform-Repository als Datenquelle im bearbeiteten Repository deklarieren. Nachdem Sie eine Datenquelle deklariert haben, können Sie darauf wie auf jede andere Dataform-Workflow-Aktion verweisen und sie zum Entwickeln Ihres Workflows verwenden.

Wenn Sie die Ausführung eines Workflows auf mehrere Repositories mit repositoryübergreifenden Abhängigkeiten aufteilen, müssen Sie die Repositories nacheinander in der Reihenfolge der repositoryübergreifenden Abhängigkeiten ausführen.

Wir empfehlen, ein Repository nicht in eine Gruppe von Repositories mit zweiseitigen Abhängigkeiten aufzuteilen. Eine beidseitige Abhängigkeit zwischen Repositories liegt vor, wenn ein Repository eine Datenquelle für ein anderes Repository ist und dieses Repository auch als Datenquelle verwendet. Zwei-Wege-Abhängigkeiten zwischen Repositories erschweren die Planung und Ausführung des übergeordneten Workflows sowie die Entwicklungsabläufe.

Code in einem Repository strukturieren

In diesem Abschnitt werden Best Practices für die Strukturierung und Benennung von Workflowdateien im Stammverzeichnis definitions eines Dataform-Repositorys beschrieben. Die empfohlene Struktur des Verzeichnisses definitions spiegelt die Phasen eines Workflows wider. Sie können eine Struktur wählen, die Ihren geschäftlichen Anforderungen entspricht.

Es gibt folgende Gründe, den Workflow-Code im Verzeichnis definitions zu strukturieren:

  • Sie können die Zusammenarbeit an der Codebasis verbessern, indem Sie Teams für ausgewählte Teile Ihres Workflows festlegen.
  • Verbesserung der Wartbarkeit des Workflows bei organisatorischen Änderungen.
  • Die Navigation durch Ihre Codebasis verbessern.
  • Verbesserung der Skalierbarkeit der Codebasis.
  • Minimieren des Verwaltungsaufwands für Ihr Team.

Das Stammverzeichnis definitions in einem Dataform-Repository enthält Code, mit dem Elemente Ihres Workflows erstellt werden. Sie können Dateien im Verzeichnis definitions in einer Verzeichnisstruktur organisieren, die der Struktur des Workflows entspricht.

Wenn Sie einen Workflow entwickeln, deklarieren Sie Quelltabellen und transformieren sie, um Ausgabetabellen zu erstellen, die Sie für Geschäfts- oder Analysezwecke verwenden können.

Es gibt drei wichtige Phasen eines Workflows:

  1. Erklärung der Datenquellen.
  2. Transformation der Quelldaten.
  3. Definition von Ausgabetabellen aus den transformierten Quelldaten.

Die folgende Struktur der Unterverzeichnisse im Verzeichnis definitions spiegelt die wichtigsten Phasen eines Workflows wider:

sources
Datenquellendeklarationen und grundlegende Transformation von Quelldaten, z. B. Filterung
intermediate
Tabellen und Aktionen, die Daten aus sources lesen und transformieren, bevor Sie die transformierten Daten zum Definieren von outputs-Tabellen verwenden. Tabellen, die nach der Ausführung in BigQuery durch Dataform in der Regel nicht zusätzlichen Prozessen oder Tools wie Business Intelligence-Tools (BI) ausgesetzt werden.
outputs
Definitionen von Tabellen, die von Prozessen oder Tools wie BI verwendet werden, nachdem sie von Dataform in BigQuery ausgeführt wurden.
extra
Dateien außerhalb der Hauptpipeline Ihres Workflows, z. B. Dateien mit Workflowdaten, die für eine zusätzliche Verwendung vorbereitet wurden, z. B. für maschinelles Lernen. Ein optionales und benutzerdefiniertes Unterverzeichnis.

Best Practices für sources

Das Unterverzeichnis sources enthält die erste Phase Ihres Workflows: die Deklaration und grundlegende Transformation der Quelldaten.

Speichern Sie im Unterverzeichnis sources Datenquellendeklarationen und Tabellen, mit denen Spalten gefiltert, kategorisiert, gewandelt oder umbenannt werden.

Speichern Sie keine Tabellen, in denen Daten aus mehreren Quellen kombiniert werden.

Transformieren Sie sources-Daten in Tabellen, die im Unterverzeichnis intermediate gespeichert sind.

Wenn Sie Datenquellen aus mehreren Pools deklarieren, z. B. aus Google Ads oder Google Analytics, weisen Sie jedem Pool ein eigenes Unterverzeichnis zu.

Das folgende Beispiel zeigt eine Unterverzeichnisstruktur von sources mit zwei Quellpools:

definitions/
    sources/
        google_ads/
            google_ads_filtered.sqlx
            google_ads_criteria_metrics.sqlx
            google_ads_criteria_metrics_filtered.sqlx
            google_ads_labels.sqlx
            google_ads_labels_filtered.sqlx
        google_analytics/
            google_analytics_users.sqlx
            google_analytics_users_filtered.sqlx
            google_analytics_sessions.sqlx

Wenn Sie mehrere Datenquellentabellen im selben Schema deklarieren, können Sie ihre Deklarationen in einer einzigen JavaScript-Datei zusammenführen.

Weitere Informationen zum Erstellen von Datenquellendeklarationen mit JavaScript finden Sie unter Dataform-Workflows mit JavaScript erstellen.

Das folgende Codebeispiel zeigt mehrere Datenquellen in einem Schema, die in einer einzigen JavaScript-Datei deklariert sind:

[
  "source_table_1",
  "source_table_2",
  "source_table_3"
].forEach((name) =>
  declare({
    database: "gcp_project",
    schema: "source_dataset",
    name,
  })
);

Um Ihren Workflow vor Änderungen an der Datenquelle zu schützen, können Sie für jede Datenquellendeklaration eine Ansicht erstellen, z. B. analytics_users_filtered.sqlx. Die Ansicht kann die grundlegende Filterung und Formatierung der Quelldaten enthalten. Speichern Sie die Ansichten im Unterverzeichnis sources.

Wenn Sie dann intermediate- oder outputs-Tabellen erstellen, verweisen Sie auf die Ansichten anstelle der Roh-Quelltabellen. Mit diesem Ansatz können Sie die Quelltabellen testen. Wenn sich eine Quelltabelle ändert, können Sie die Ansicht ändern, z. B. durch Hinzufügen von Filtern oder Umwandeln von Daten.

Best Practices für intermediate

Das Unterverzeichnis intermediate enthält die zweite Phase Ihres Workflows: die Transformation und Aggregation der Quelldaten aus einer oder mehreren Quellen.

Speichern Sie im Unterverzeichnis intermediate Dateien, die Quelldaten aus einer oder mehreren Quellen im Unterverzeichnis sources erheblich transformieren, z. B. Tabellen, die Daten zusammenführen. In Tabellen im Unterverzeichnis intermediate werden in der Regel Daten aus Quelltabellen oder anderen intermediate-Tabellen abgefragt.

Mit intermediate-Tabellen können Sie outputs-Tabellen erstellen. Normalerweise werden intermediate-Tabellen nicht für zusätzliche Zwecke wie Datenanalysen verwendet, nachdem sie von Dataform in BigQuery ausgeführt wurden. Sie können sich intermediate-Tabellen als die Logik der Datentransformation vorstellen, die das Erstellen von Ausgabetabellen ermöglicht.

Wir empfehlen, alle intermediate-Tabellen zu dokumentieren und zu testen.

Best Practices für outputs

Das Unterverzeichnis outputs enthält die letzte Phase Ihres Workflows: die Erstellung von Ausgabetabellen für Ihre geschäftlichen Zwecke aus den transformierten Daten.

Speichern Sie im Verzeichnis outputs Tabellen, die Sie in zusätzlichen Prozessen oder Tools verwenden möchten, nachdem sie von Dataform in BigQuery ausgeführt wurden, z. B. Berichte oder Dashboards. In Tabellen im Verzeichnis outputs werden in der Regel Daten aus den intermediate-Tabellen abgefragt.

Gruppieren Sie outputs-Tabellen nach dem zugehörigen Geschäftsobjekt, z. B. „Marketing“, „Bestellungen“ oder „Analysen“. Weisen Sie jedem Geschäftsentität ein eigenes Unterverzeichnis zu.

Wenn Sie Ausgabetabellen separat in BigQuery speichern möchten, können Sie ein spezielles Schema für Ausgabetabellen konfigurieren. Eine Anleitung zum Konfigurieren des Tabellenschemas finden Sie unter Zusätzliche Tabelleneinstellungen konfigurieren.

Das folgende Beispiel zeigt eine Unterverzeichnisstruktur von outputs mit den Geschäftsentitäten sales und marketing:

definitions/
    outputs/
        orders/
            orders.sqlx
            returns.sqlx
        sales/
            sales.sqlx
            revenue.sqlx
        marketing/
            campaigns.sqlx

Wir empfehlen, alle outputs-Tabellen zu dokumentieren und zu testen.

Benennungsstrategie

Die Namen aller Dateien in Dataform müssen den Richtlinien für die Benennung von BigQuery-Tabellen entsprechen.

Wir empfehlen, dass die Namen der Dateien im Verzeichnis definitions in einem Dataform-Repository der Struktur der Unterverzeichnisse entsprechen.

Im Unterverzeichnis sources sollten die Dateinamen auf die Quelle verweisen, mit der die Datei verknüpft ist. Fügen Sie den Namen der Quelle als Präfix zu den Dateinamen hinzu, z. B. analytics_filtered.sqlx

Im Unterverzeichnis intermediate sollten die Dateinamen das Unterverzeichnis identifizieren, damit Mitbearbeiter intermediate-Dateien klar unterscheiden können. Wählen Sie ein eindeutiges Präfix aus und wenden Sie es nur auf Dateien im Verzeichnis intermediate an, z. B. stg_ads_concept.sqlx.

Die Dateinamen im Unterverzeichnis outputs sollten prägnant sein, z. B. orders.sqlx. Wenn Sie outputs-Tabellen mit denselben Namen in verschiedenen Entitätsunterverzeichnissen haben, fügen Sie ein Präfix hinzu, das die Entität identifiziert, z. B. sales_revenue.sqlx oder ads_revenue.sqlx.

Das folgende Beispiel zeigt eine Unterverzeichnisstruktur im Verzeichnis definitions mit Dateinamen, die der empfohlenen Benennungsstrategie entsprechen:

definitions/
    sources/
        google_analytics.sqlx
        google_analytics_filtered.sqlx
    intermediate/
        stg_analytics_concept.sqlx
    outputs/
        customers.sqlx
        sales/
            sales.sqlx
            sales_revenue.sqlx
        ads/
            campaigns.sqlx
            ads_revenue.sqlx

Nächste Schritte