Data: faites appel à un plombier
Équipe DATA
- Géomaticiens
- Experts PostgreSQL
- Développeurs
Équipe COPS
Luigi
Très peu de fonctionnalités
N'évolue plus beaucoup
Pas de scalabilité automagique
Tout est chaîné statiquement
Tout ou rien
Va consommer (vraiment) beaucoup d'espace disque
Impossible de lancer 2 fois le même traitement
Une fois le traitement terminé, le worker s'éteint
Pas fait pour du temps réel
Pas fait pour avoir des worflows de plusieurs millions de tâches
En gros, ne tiens pas la comparaison avec Airflow
Voilà, voilà ...
L'inspiration : GNU Make
2 notions à connaître
ConstruireCarte(realtor_id=2248)
Workflow
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : découverte
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : découverte
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : découverte
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : découverte
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : découverte
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : exécution
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : exécution
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : exécution
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : reprise
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : reprise
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : reprise
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : reprise
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : reprise
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Workflow : reprise
ConstruireCarte(realtor_id=2248)
GeoJSONSilver(realtor_id=2248)
GeoJSONGold(realtor_id=2248)
ClassementAgence(address_id=1)
CollectData(realtor_id=2248)
ClassementAgence(address_id=2)
ClassementAgence(address_id=3)
Task
import luigi
class MyTask(luigi.Task):
param = luigi.Parameter(default=42)
def requires(self):
return SomeOtherTask(self.param)
def run(self):
with self.output().open("w") as output:
output.write("Hello, world")
def output(self):
return luigi.LocalTarget("/tmp/foo/bar-%s.txt" % self.params)
Target
import contextlib
import luigi
class MyTarget(luigi.Target):
def exists(self):
""" Return true if data already exists """
@contextlib.contextmanager
def open(self):
""" Not required but recommanded """
Execution
luigi --module CarteVisibilite ConstruireCarte --realtor_id 2248 [--local-scheduler]
import luigi
from carte_visibilite import ConstruireCarte
luigi.build([ConstruireCarte(realtor_id=2248)], workers=10)
Patterns plutôt que fonctionnalités
import itertools
class DummyTarget(luigi.Target):
def __init__(self):
self.result_gen = itertools.chain(
(False, ), itertools.repeat(True)
)
def exists(self):
return next(self.result_gen)
Pattern COMMANDE
Quelques outils
Cas d'usage
Production incrémentale
Équipe de développeurs Python
Livrable == base
Ensemble cohérent de données
Yoshi
Synchro de base de données pour une mailing list
Assets generator
Carte de visibilité
Applaudissez-moi !
Maintenant !!
Data: faites appel à un plombier
By Romain Commandé
Data: faites appel à un plombier
- 735