Couche de tests unitaires native pour les data engineers. MockSQL choisit un fichier .sql, génère automatiquement des jeux de données de test cohérents via LLM, les exécute localement sur DuckDB (0 € facturé sur BigQuery), attribue un verdict argumenté à chaque test, et suggère les cas limites non couverts.
Les bibliothèques de mocking SQL existantes vous demandent d'écrire les données de test à la main dans du code Python. MockSQL prend le contrepied :
| Bibliothèques de mocking SQL | MockSQL | |
|---|---|---|
| Données de test | Écrites manuellement par l'ingé | Générées automatiquement par LLM |
| Couverture | Aucune détection — l'ingé doit y penser | 6 axes (NULL, vide, ex æquo…) + suggestions |
| Qualité du test | Pas d'évaluation | Verdict LLM (bon / insuffisant / incorrect) |
| Interface | Bibliothèque Python dans du code de test | UI dédiée (GenerateView → TestsView) |
| Dérive | Inexistante | Roadmap : alerte si le SQL prod a changé |
| Moteur SQL | Un connecteur par DB | DuckDB unifié — aucun coût BigQuery |
MockSQL se décline en deux modes :
- CLI (
mocksql) — usage standalone directement sur tes fichiers.sqllocaux - Web Hub — interface complète avec historique, verdicts, couverture et collaboration
pip install dist/mocksql-*.whl
export PROJECT_ID=<votre-projet-gcp>
# 1. Initialiser un projet
mocksql init
# 2. Générer des tests pour un modèle SQL
mocksql generate models/my_model.sqlVoir la section CLI pour le détail.
- Python 3.11+
- Poetry (
pip install poetry) — pour le développement depuis les sources - Node.js 18+ — pour builder le frontend (pas requis à l'exécution)
- Google Cloud SDK
Les modèles Gemini (VertexAI) et BigQuery utilisent les credentials applicatifs Google :
gcloud auth application-default login
gcloud config set project <PROJECT_ID>Le compte utilisé (utilisateur ou service account) doit disposer des rôles suivants sur le projet GCP :
| Rôle | Utilité |
|---|---|
BigQuery Data Viewer (roles/bigquery.dataViewer) |
Lecture du schéma des tables |
BigQuery User (roles/bigquery.user) |
Lancement des jobs / dry-run des requêtes |
AI Platform Developer (roles/aiplatform.user) |
Appels aux modèles Vertex AI (Gemini) |
Activation des modèles Gemini (étape unique par projet) Les rôles IAM ne suffisent pas : même avec
roles/aiplatform.user, les modèles Gemini retournent une erreur 404 si l'accès n'a pas été activé dans le Model Garden. Dans la console GCP, ouvrez Model Garden, cherchez un modèle Gemini (ex. Gemini 2.0 Flash Lite) et acceptez les conditions d'utilisation. Cette opération est unique par projet GCP et ne peut pas être réalisée viagcloud.
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member='user:<votre-email@domaine.com>' \
--role='roles/bigquery.dataViewer'
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member='user:<votre-email@domaine.com>' \
--role='roles/bigquery.user'
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member='user:<votre-email@domaine.com>' \
--role='roles/aiplatform.user'-
Créez un service account et attribuez-lui les mêmes rôles :
SA_EMAIL="mocksql-sa@<PROJECT_ID>.iam.gserviceaccount.com" gcloud iam service-accounts create mocksql-sa \ --project=<PROJECT_ID> \ --display-name="MockSQL service account" for ROLE in roles/bigquery.dataViewer roles/bigquery.user roles/aiplatform.user; do gcloud projects add-iam-policy-binding <PROJECT_ID> \ --member="serviceAccount:${SA_EMAIL}" \ --role="${ROLE}" done
-
Générez une clé JSON et pointez-y via
GOOGLE_APPLICATION_CREDENTIALS:gcloud iam service-accounts keys create ~/keys/mocksql-sa.json \ --iam-account="${SA_EMAIL}"
# back/.env GOOGLE_APPLICATION_CREDENTIALS=/chemin/vers/mocksql-sa.json
Erreur fréquente :
Forbidden: Access Denied: bigquery.jobs.create permission→ Le rôle BigQuery User est manquant sur le projet.
cp back/.env.example back/.envVariables essentielles :
# Google Cloud
PROJECT_ID=<votre-projet-gcp>
GOOGLE_CLOUD_PROJECT=<votre-projet-gcp>
GOOGLE_CLOUD_LOCATION=us-central1
# BigQuery (import de schémas)
BQ_SCHEMA_BILLING_PROJECT=<votre-projet-gcp>
BQ_REGION=US
# LLM (peut être overridé dans mocksql.yml via llm.model)
DEFAULT_MODEL_NAME=gemini-2.0-flash-lite
# Base de données locale
DUCKDB_PATH=data/mocksql.duckdb
# Sécurité
SECRET_KEY=<clé-secrète>
API_SECRET_KEY=<clé-api>
# CORS
FRONT_URL=http://127.0.0.1:3000cd back
python -m venv .venv
# Linux / macOS
source .venv/bin/activate
# Windows
.\.venv\Scripts\activate
pip install poetry && poetry installuvicorn server:app --port 8080 --reloadLe backend est accessible sur http://localhost:8080.
Pour l'usage CLI standalone (sans back/.env), définir les variables suivantes dans votre shell ou un fichier .env à la racine de votre projet :
PROJECT_ID=<votre-projet-gcp>
GOOGLE_CLOUD_PROJECT=<votre-projet-gcp>
GOOGLE_CLOUD_LOCATION=us-central1
DUCKDB_PATH=data/mocksql.duckdbGOOGLE_CLOUD_LOCATION est obligatoire pour les appels Vertex AI — sans elle, les modèles Gemini ne sont pas accessibles.
Initialise un projet MockSQL et génère mocksql.yml :
mocksql init
# ou dans un sous-dossier
mocksql init --path ./mon_projetExemple de mocksql.yml généré :
version: "2"
dialect: bigquery # bigquery | postgres
models_path: ./models
llm:
provider: vertexai # vertexai | openai
model: gemini-2.0-flash # override du modèle par défaut (optionnel)
streaming: false # désactive le streaming LLM (optionnel)
schema_cache: .mocksql/schema_cache.jsonClés de la section llm :
| Clé | Défaut | Description |
|---|---|---|
provider |
vertexai |
Backend LLM (vertexai ou openai) |
model |
gemini-2.0-flash-lite |
Nom du modèle — prioritaire sur DEFAULT_MODEL_NAME |
streaming |
false |
Active ou désactive le streaming token par token |
Parse un modèle SQL, résout les schémas des tables sources et génère des données de test :
mocksql generate models/orders.sql
# options
mocksql generate models/orders.sql --config mocksql.yml --output .mocksql/testsLes schémas récupérés sont mis en cache dans .mocksql/schema_cache.json — les runs suivants n'interrogent plus BigQuery.
Outputs dans .mocksql/tests/ :
<model>_data.json— données de test (tables d'entrée)<model>_results.json— résultats d'exécution DuckDB
Si tes fichiers .sql contiennent des variables non-parsables (@start_date, {{ ds }}, macros dbt…), déclare une fonction Python dans mocksql.yml pour les remplacer avant analyse :
# mocksql.yml
preprocessor_fn: "preprocessors:replace_vars" # module:fonction, relatif au mocksql.ymlCrée preprocessors.py à côté de mocksql.yml :
import re
def replace_vars(sql: str) -> str:
defaults = {"start_date": "'2024-01-01'", "end_date": "'2024-12-31'"}
return re.sub(r"@(\w+)", lambda m: defaults.get(m.group(1), "NULL"), sql)La fonction reçoit le SQL brut et retourne le SQL transformé. Elle est appelée aussi bien par mocksql generate que par l'UI lors de la lecture des modèles.
Un exemple complet est disponible dans examples/jaffle_shop/ :
mocksql generate examples/jaffle_shop/models/orders.sql \
--config examples/jaffle_shop/mocksql.ymlMockSQL distribue deux wheels distincts :
| Package | Contenu | Usage |
|---|---|---|
mocksql |
CLI (mocksql init, mocksql generate) |
CI/CD, sans UI |
mocksql-ui |
CLI + serveur web + assets React | Installation complète |
# CLI uniquement
pip install dist/mocksql-*.whl
# CLI + UI
pip install dist/mocksql-*.whl dist/mocksql_ui-*.whlcd back
# CLI uniquement
make build-cli
# CLI + UI (build React inclus, Node.js requis)
make build-ui # produit dist/mocksql-*.whl et dist/mocksql_ui-*.whlmocksql ui # http://localhost:8080/static/
mocksql ui --port 4000 # port personnalisé
mocksql ui --no-browser # sans ouverture automatique du navigateurNode.js n'est pas requis à l'exécution — uniquement pour le build.
cd front
npm ci
npm start # http://localhost:3000 (proxy vers le backend sur :8080)back/ # FastAPI + LangGraph + CLI
cli/ # mocksql CLI (main.py, generate.py)
ui/ # package mocksql-ui (serveur + assets React)
front/ # React 18 + TypeScript + Redux (Web Hub)
examples/ # Exemples de projets MockSQL
docs/ # Documentation du workflow
| Commande | Description |
|---|---|
make style |
Lint (ruff) + format check + code mort (vulture) |
make format |
Auto-format et auto-fix ruff |
make test |
Tests pytest |
make check |
style + test |
pip install pre-commit
pre-commit installmake style sera exécuté automatiquement à chaque git commit sur les fichiers Python modifiés.