adstoolbox 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
adsToolBox/__init__.py ADDED
@@ -0,0 +1,12 @@
1
+ from .logger import Logger
2
+ from .timer import timer, get_timer
3
+ from .global_config import set_timer
4
+ from .dbPgsql import dbPgsql
5
+ from .dbMssql import dbMssql
6
+ from .pipeline import pipeline
7
+ from .wait_file import wait_for_file
8
+
9
+
10
+ __all__ = [
11
+ "Logger", "timer", "set_timer", "get_timer", "dbPgsql", "dbMssql", "pipeline", "wait_for_file"
12
+ ]
@@ -0,0 +1,22 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+
4
+ class data_factory(ABC):
5
+
6
+ @abstractmethod
7
+ def connect(self):
8
+ pass
9
+ @abstractmethod
10
+ def insert(self,table,cols=[],rows=[]):
11
+ pass
12
+
13
+ @abstractmethod
14
+ def insertBulk(self,table,cols=[],rows=[]):
15
+ pass
16
+ @abstractmethod
17
+ def sqlQuery(self,query):
18
+ pass
19
+
20
+ @abstractmethod
21
+ def sqlExec(self, query: str, params=None):
22
+ pass
adsToolBox/dbMssql.py ADDED
@@ -0,0 +1,119 @@
1
+ from datetime import datetime
2
+ import pymssql
3
+ import timeit
4
+ from .timer import timer, get_timer
5
+ from .dataFactory import data_factory
6
+
7
+ class dbMssql(data_factory):
8
+
9
+ def __init__(self, dictionnary: dict, logger, batch_size=10_000):
10
+ self.connection = None
11
+ self.logger = logger
12
+ self.__database = dictionnary['database']
13
+ self.__user = dictionnary['user']
14
+ self.__password = dictionnary['password']
15
+ self.__port = dictionnary['port']
16
+ self.__host = dictionnary['host']
17
+ self.__batch_size = batch_size
18
+
19
+ @timer
20
+ def connect(self):
21
+ if self.logger is not None: self.logger.info("Tentative de connexion avec la base de données.")
22
+ try:
23
+ self.connection = pymssql.connect(
24
+ server=f"{self.__host}:{self.__port}",
25
+ user=self.__user,
26
+ password=self.__password,
27
+ database=self.__database
28
+ )
29
+ if self.logger is not None: self.logger.info(f"Connexion établie avec la base de données.")
30
+ return self.connection
31
+ except Exception as e:
32
+ if self.logger is not None: self.logger.error(f"Échec de la connexion à la base de données: {e}")
33
+ raise
34
+
35
+ def sqlQuery(self, query):
36
+ self.logger.debug(f"Exécution de la requête de lecture : {query}")
37
+ start_time = datetime.now()
38
+ try:
39
+ timer_start = timeit.default_timer()
40
+ with self.connection.cursor() as cursor:
41
+ cursor.execute(query)
42
+ cols = [desc[0] for desc in cursor.description]
43
+ self.logger.info("Requête exécutée avec succès, début de la lecture des résultats.")
44
+ while True:
45
+ rows = cursor.fetchmany(self.__batch_size)
46
+ if not rows:
47
+ break
48
+ yield from rows
49
+ self.logger.info(f"{len(rows)} lignes lues.")
50
+ end_time = datetime.now()
51
+ self.logger.log_to_db(start_time, end_time, status='success', message="Requête de lecture exécutée.")
52
+ if get_timer():
53
+ elapsed_time = timeit.default_timer() - timer_start
54
+ self.logger.info(f"Temps d'exécution de sqlQuery: {elapsed_time:.4f} secondes")
55
+ except Exception as e:
56
+ end_time = datetime.now()
57
+ self.logger.error(f"Échec de la lecture des données: {e}")
58
+ self.logger.log_to_db(start_time, end_time, status="failure", message=str(e))
59
+ raise
60
+
61
+ @timer
62
+ def sqlExec(self, query):
63
+ try:
64
+ with self.connection.cursor() as cursor:
65
+ cursor.execute(query)
66
+ self.logger.info(f"Requête exécutée avec succès.")
67
+ self.connection.commit()
68
+ except Exception as e:
69
+ self.logger.error(f"Échec de l'exécution de la requête: {e}")
70
+ raise
71
+
72
+ @timer
73
+ def sqlScalaire(self, query):
74
+ try:
75
+ with self.connection.cursor() as cursor:
76
+ cursor.execute(query)
77
+ self.logger.info(f"Requête exécutée avec succès.")
78
+ data = cursor.fetchone()
79
+ return data
80
+ except Exception as e:
81
+ self.logger.error(f"Échec de l'exécution de la requête: {e}")
82
+ raise
83
+
84
+
85
+ @timer
86
+ def insert(self, table, cols=[], rows=[]):
87
+ start_time = datetime.now()
88
+ try:
89
+ with self.connection.cursor() as cursor:
90
+ placeholders = ", ".join(["%s"] * len(cols))
91
+ query = f"INSERT INTO {table} ({', '.join(cols)}) VALUES ({placeholders})"
92
+ cursor.execute(query, rows)
93
+ self.connection.commit()
94
+ self.logger.info(f"{cursor.rowcount} lignes insérées avec succès dans la table {table}.")
95
+ self.logger.log_to_db(start_time, datetime.now(), status='success', message="Insertion réussie.")
96
+ return ["SUCCESS"]
97
+ except Exception as e:
98
+ self.logger.error(f"Échec de l'insertion des données: {e}")
99
+ self.logger.log_to_db(start_time, datetime.now(), status='failure', message=str(e))
100
+ self.connection.rollback()
101
+ return "ERROR", str(e), rows
102
+
103
+ @timer
104
+ def insertBulk(self, table, cols=[], rows=[]):
105
+ start_time = datetime.now()
106
+ try:
107
+ with self.connection.cursor() as cursor:
108
+ placeholders = ", ".join(["%s"] * len(cols))
109
+ query = f"INSERT INTO {table} ({', '.join(cols)}) VALUES ({placeholders})"
110
+ cursor.executemany(query, rows)
111
+ self.connection.commit()
112
+ self.logger.info(f"{cursor.rowcount} lignes insérées avec succès dans la table {table}.")
113
+ self.logger.log_to_db(start_time, datetime.now(), status='success', message="Insertion réussie.")
114
+ return ["SUCCESS"]
115
+ except Exception as e:
116
+ self.logger.error(f"Échec de l'insertion des données: {e}")
117
+ self.logger.log_to_db(start_time, datetime.now(), status='failure', message=str(e))
118
+ self.connection.rollback()
119
+ return "ERROR", str(e), rows
adsToolBox/dbPgsql.py ADDED
@@ -0,0 +1,119 @@
1
+ from datetime import datetime
2
+ import psycopg2
3
+ import timeit
4
+ from .timer import timer, get_timer
5
+ from .dataFactory import data_factory
6
+
7
+ class dbPgsql(data_factory):
8
+
9
+ def __init__(self, dictionnary: dict, logger, batch_size=10_000):
10
+ self.connection = None
11
+ self.logger = logger
12
+ self.__database = dictionnary['database']
13
+ self.__user = dictionnary['user']
14
+ self.__password = dictionnary['password']
15
+ self.__port = dictionnary['port']
16
+ self.__host = dictionnary['host']
17
+ self.__batch_size = batch_size
18
+
19
+ @timer
20
+ def connect(self):
21
+ if self.logger is not None: self.logger.info("Tentative de connexion avec la base de données.")
22
+ try:
23
+ self.connection = psycopg2.connect(
24
+ database=self.__database,
25
+ user=self.__user,
26
+ password=self.__password,
27
+ port=self.__port,
28
+ host=self.__host
29
+ )
30
+ if self.logger is not None: self.logger.info(f"Connexion établie avec la base de données.")
31
+ return self.connection
32
+ except Exception as e:
33
+ if self.logger is not None: self.logger.error(f"Échec de la connexion à la base de données.")
34
+ raise
35
+
36
+ def sqlQuery(self, query: str):
37
+ self.logger.debug(f"Exécution de la requête de lecture: {query}")
38
+ start_time = datetime.now()
39
+ try:
40
+ timer_start = timeit.default_timer()
41
+ with self.connection.cursor() as cursor:
42
+ cursor.execute(query)
43
+ cols = [desc for desc in cursor.description]
44
+ self.logger.info("Requête exécutée avec succès, début de la lecture des résultats.")
45
+ while True:
46
+ rows = cursor.fetchmany(self.__batch_size)
47
+ if not rows:
48
+ break
49
+ yield rows
50
+ self.logger.info(f"{len(rows)} ligne(s) lue(s).")
51
+ end_time = datetime.now()
52
+ self.logger.log_to_db(start_time, end_time, status='success', message='Requête de lecture exécutée')
53
+ if get_timer():
54
+ elapsed_time = timeit.default_timer() - timer_start
55
+ self.logger.info(f"Temps d'exécution de sqlQuery: {elapsed_time:.4f} secondes")
56
+ except Exception as e:
57
+ end_time = datetime.now()
58
+ self.logger.error(f"Échec de la lecture des données: {e}")
59
+ self.logger.log_to_db(start_time, end_time, status="failure", message=str(e))
60
+ raise
61
+
62
+ @timer
63
+ def sqlExec(self, query):
64
+ try:
65
+ with self.connection.cursor() as cursor:
66
+ cursor.execute(query)
67
+ self.logger.info(f"Requête exécutée avec succès.")
68
+ self.connection.commit()
69
+ except Exception as e:
70
+ self.logger.error(f"Échec de l'exécution de la requête: {e}")
71
+ raise
72
+
73
+ @timer
74
+ def sqlScalaire(self, query):
75
+ try:
76
+ with self.connection.cursor() as cursor:
77
+ cursor.execute(query)
78
+ self.logger.info(f"Requête exécutée avec succès.")
79
+ data = cursor.fetchone()
80
+ return data
81
+ except Exception as e:
82
+ self.logger.error(f"Échec de l'exécution de la requête: {e}")
83
+ raise
84
+
85
+ @timer
86
+ def insert(self, table, cols=[], rows=[]):
87
+ start_time = datetime.now()
88
+ try:
89
+ with self.connection.cursor() as cursor:
90
+ placeholders = ", ".join(["%s"] * len(cols))
91
+ query = f"INSERT INTO {table} ({', '.join(cols)}) VALUES ({placeholders})"
92
+ cursor.execute(query, rows)
93
+ self.connection.commit()
94
+ self.logger.info(f"{cursor.rowcount} ligne insérée avec succès dans la table {table}.")
95
+ self.logger.log_to_db(start_time, datetime.now(), status='success', message="Insertion réussie.")
96
+ return ["SUCCESS"]
97
+ except Exception as e:
98
+ self.logger.error(f"Échec de l'insertion des données: {e}")
99
+ self.logger.log_to_db(start_time, datetime.now(), status='failure', message=str(e))
100
+ self.connection.rollback()
101
+ return "ERROR", str(e), rows
102
+
103
+ @timer
104
+ def insertBulk(self, table, cols=[], rows=[]):
105
+ start_time = datetime.now()
106
+ try:
107
+ with self.connection.cursor() as cursor:
108
+ placeholders = ", ".join(["%s"] * len(cols))
109
+ query = f"INSERT INTO {table} ({', '.join(cols)}) VALUES ({placeholders})"
110
+ cursor.executemany(query, rows)
111
+ self.connection.commit()
112
+ self.logger.info(f"{cursor.rowcount} lignes insérées avec succès dans la table {table}.")
113
+ self.logger.log_to_db(start_time, datetime.now(), status="success", message="Insertion(s) réussie(s)")
114
+ return ["SUCCESS"]
115
+ except Exception as e:
116
+ self.logger.error(f"Échec de l'insertion des données: {e}")
117
+ self.logger.log_to_db(start_time, datetime.now(), status="failure", message=str(e))
118
+ self.connection.rollback()
119
+ return "ERROR", str(e), rows
@@ -0,0 +1,63 @@
1
+ import adsToolBox as ads
2
+ from to_sort.env import *
3
+ import os
4
+
5
+ ads.set_timer(True) # active les timer
6
+
7
+ #--------------------------------------------------------------------------------------
8
+ #--------------------- DATA PIPELINE DB to DB -------------------------
9
+ #--------------------------------------------------------------------------------------
10
+
11
+ def pipeline():
12
+ pg_source=ads.dbPgsql({'database':pg_dwh_db
13
+ , 'user':pg_dwh_user
14
+ , 'password':pg_dwh_pwd
15
+ , 'port':pg_dwh_port
16
+ , 'host':pg_dwh_host})
17
+
18
+ mssql_destination=ads.dbMssql({'database': mssql_dwh_db
19
+ , 'user':mssql_dwh_user
20
+ , 'password':mssql_dwh_pwd
21
+ , 'port':mssql_dwh_port
22
+ , 'host':mssql_dwh_host})
23
+
24
+
25
+ mypipeline=ads.pipelineBulk({'db_source':pg_source
26
+ ,'query_source':'''SELECT tenantname, taille, unite, fichier FROM onyx_qs."diskcheck" LIMIT 10'''
27
+ ,'db_destination':mssql_destination
28
+ ,'table':'ONYX.diskcheck'
29
+ ,'cols':['tenantname', 'taille', 'unite', 'fichier']})
30
+
31
+
32
+ mssql_destination=ads.dbMssql({'database': mssql_dwh_db
33
+ , 'user':mssql_dwh_user
34
+ , 'password':mssql_dwh_pwd
35
+ , 'port':mssql_dwh_port
36
+ , 'host':mssql_dwh_host})
37
+
38
+
39
+ mypipeline=ads.pipeline({'db_source':pg_source
40
+ ,'query_source':'''SELECT tenantname, taille, unite, fichier FROM onyx_qs."diskcheck" LIMIT 10'''
41
+ ,'db_destination':mssql_destination
42
+ ,'table':'ONYX.diskcheck'
43
+ ,'cols':['tenantname', 'taille', 'unite', 'fichier']})
44
+
45
+ mypipeline.run()
46
+
47
+ #--------------------------------------------------------------------------------------
48
+ #---------------------------- FICHIERS --------------------------------
49
+ #--------------------------------------------------------------------------------------
50
+
51
+ def fichier():
52
+ # lister un dossier
53
+ os.listdir()
54
+
55
+ # Copier un fichier
56
+ #shutil.copy("trashcan.py", "../factory")
57
+
58
+ #shutil.copy2() #--> conserve les metadata
59
+
60
+ # Vérifier l'existance d'un fichier
61
+ #os.path.isfile("")
62
+
63
+ pipeline()
@@ -0,0 +1,15 @@
1
+ import polars as pl
2
+
3
+ tbl = [
4
+ ("A", "1"),
5
+ ("B", "2"),
6
+ ("C", "3"),
7
+ ("C", "3"),
8
+ ("C", "3")
9
+ ]
10
+
11
+ df = pl.DataFrame(tbl, schema=["key", "value"], orient="row")
12
+
13
+ df = df.unique()
14
+
15
+ print(df)
@@ -0,0 +1,50 @@
1
+ import shutil
2
+ import polars as pl
3
+ import os
4
+
5
+ data = [
6
+ ("A", 1, 10.5, 'He said "Hello"'),
7
+ ("B", 2, 20.1, "NA"),
8
+ ("C", 3, 30.7, "NA"),
9
+ ("D", "NA", 40.6, "NA")
10
+ ]
11
+ df = pl.DataFrame(data, schema=["key", "value1", "value2", "value3"], orient="row")
12
+
13
+ # Écriture dans un fichier csv
14
+ csv_file = "example_data.csv"
15
+ df.write_csv(csv_file, separator=";", quote_char='"', include_header=True)
16
+
17
+ # Lecture à partir d'un fichier csv
18
+ df_csv = pl.read_csv(
19
+ "example_data.csv",
20
+ separator=";", #Utiliser un séparateur précis, par défaut ","
21
+ has_header=True, #Indique si le fichier a une ligne d'en-tête
22
+ null_values=["NA"], #Interpréter ces valeurs comme nulles
23
+ columns=["key", "value1", "value3"], #Lire uniquement certaines colonnes
24
+ quote_char='"' #Le caractère utilisé pour entourer les valeurs est le double guillemet
25
+ )
26
+ print(df_csv)
27
+
28
+ # Lister les fichiers du répertoire courant
29
+ print(os.listdir())
30
+
31
+ # Créer et écrire dans un fichier txt
32
+ with open("file.txt", "w") as file:
33
+ file.write("Your text goes here")
34
+
35
+ # Copier un fichier
36
+ shutil.copy("file.txt", "copy.txt")
37
+
38
+ # Copier les métadonnées
39
+ shutil.copy2("file.txt", "copy2.txt")
40
+
41
+ # Vérifier si un fichier est présent ou non
42
+ if os.path.isfile("copy.txt"):
43
+ print("Le fichier est bien présent.")
44
+ else:
45
+ print("Le fichier n'est pas présent.")
46
+
47
+ # Supprime un fichier
48
+ os.remove("copy.txt")
49
+ os.remove("copy2.txt")
50
+ os.remove("file.txt")
@@ -0,0 +1,25 @@
1
+ import polars as pl
2
+
3
+ tbl1 = [
4
+ ("A", "1"),
5
+ ("B", "2"),
6
+ ("C", "3"),
7
+ ("D", "4")
8
+ ]
9
+
10
+ df1 = pl.DataFrame(tbl1, schema=["key", "value1"], orient="row")
11
+ tbl2 = [
12
+ ("A", "10"),
13
+ ("B", "20"),
14
+ ("C", "40"),
15
+ ]
16
+
17
+ df2 = pl.DataFrame(tbl2, schema=["key", "value2"], orient="row")
18
+
19
+ # Inner join
20
+ df_joined = df1.join(df2, on="key", how="inner")
21
+ print(df_joined)
22
+
23
+ # Left join
24
+ df_left_joined = df1.join(df2, on="key", how="left")
25
+ print(df_left_joined)
@@ -0,0 +1,16 @@
1
+ import polars as pl
2
+
3
+ tbl = [
4
+ ("A", "5"),
5
+ ("C", "3"),
6
+ ("E", "1"),
7
+ ("D", "2"),
8
+ ("B", "4")
9
+ ]
10
+ df = pl.DataFrame(tbl, schema=["key", "value"], orient="row")
11
+
12
+ df = df.sort("key")
13
+ print(df)
14
+
15
+ df = df.sort("value")
16
+ print(df)
@@ -0,0 +1,19 @@
1
+ import polars as pl
2
+
3
+ tbl = [
4
+ ("A A A A", "1"),
5
+ ("B V", "2"),
6
+ ("CZZ ZDQS", "3"),
7
+ ("CQSD d", "4"),
8
+ ("CDAS AZDASD", "5")
9
+ ]
10
+ df = pl.DataFrame(tbl, schema=["key", "value"], orient="row")
11
+ print(df)
12
+
13
+ #Suppression des espaces sur une colonne
14
+ df = df.with_columns(pl.col("key").str.replace_all(" ", ""))
15
+ print(df)
16
+
17
+ #Concaténation de 2 champs
18
+ df = df.with_columns(pl.concat_str(["key", "value"], separator="-").alias("value2"))
19
+ print(df)
File without changes
@@ -0,0 +1,62 @@
1
+ from adsToolBox import timer
2
+ from adsToolBox.dbPgsql import dbPgsql
3
+ from adsToolBox.logger import Logger
4
+ from adsToolBox.global_config import set_timer
5
+ import time
6
+
7
+ from to_sort.env import *
8
+ import logging
9
+
10
+ # Établit une connexion pour que le logger puisse écrire en base
11
+ logger_connection = dbPgsql({'database': pg_dwh_db
12
+ , 'user': pg_dwh_user
13
+ , 'password': pg_dwh_pwd
14
+ , 'port': pg_dwh_port
15
+ , 'host': pg_dwh_host},
16
+ None)
17
+ # Ne pas oublier de lancer la connection
18
+ logger_connection.connect()
19
+
20
+ logger = Logger(logger_connection, logging.INFO, "AdsLogger", "LOGS", "LOGS_details")
21
+ logger.info("Début de la démonstration.")
22
+
23
+ # Active le timer, les requêtes seront chronométrées, si le logger n'est pas activé, les temps d'exécutions ne seront pas affichés
24
+ set_timer(True)
25
+
26
+ # On définit une source de connexion à laquelle on affecte notre logger
27
+ source = dbPgsql({'database': pg_dwh_db
28
+ , 'user': pg_dwh_user
29
+ , 'password': pg_dwh_pwd
30
+ , 'port': pg_dwh_port
31
+ , 'host': pg_dwh_host},
32
+ logger)
33
+
34
+ # Cette opération sera loguée et chronométrée
35
+ source.connect()
36
+
37
+ # Celle-ci le sera dès que le flux (générateur) renvoyé par sqlQuery sera consommé
38
+ data1 = source.sqlQuery('''SELECT tenantname, fichier FROM onyx_qs."diskcheck" LIMIT 10''')
39
+ print(f"Première requête: {list(data1)}")
40
+ # Après ce print viennent les notifications d'insertions des logs en base et le temps d'eéxuction
41
+
42
+ # Voici comment désactiver les logs
43
+ logger.disable()
44
+ logger.info("Ceci est un message d'information qui n'est pas censé s'afficher.")
45
+
46
+ data2 = source.sqlQuery('''SELECT tenantname, fichier FROM onyx_qs."diskcheck" LIMIT 10''')
47
+ print(f"Seconde requête: {list(data2)}")
48
+ # Ici pas d'insertions en base de logs non plus, et pas de temps d'exécutions affiché
49
+
50
+ # On peut aussi affecter le décorateur timer à n'importe quelle méthode
51
+ @timer
52
+ def sample_function(duration, logger=None):
53
+ """ Une fonction d'exemple qui simule une tâche en attendant un certain temps. """
54
+ time.sleep(duration)
55
+ return "Done"
56
+
57
+ # Par contre, il faut absolument un argument 'logger' dans la fonction en question
58
+ logger.enable()
59
+ sample_function(0.1, logger=logger)
60
+
61
+
62
+ logger.info("Fin de la démonstration !")
@@ -0,0 +1,88 @@
1
+ from adsToolBox.logger import Logger
2
+ from adsToolBox.dbPgsql import dbPgsql
3
+ from adsToolBox.global_config import set_timer
4
+ from adsToolBox.pipeline import pipeline
5
+
6
+ from to_sort.env import *
7
+ import logging
8
+
9
+ logger_connection = dbPgsql({'database': pg_dwh_db
10
+ , 'user': pg_dwh_user
11
+ , 'password': pg_dwh_pwd
12
+ , 'port': pg_dwh_port
13
+ , 'host': pg_dwh_host},
14
+ None, 10_000)
15
+ logger_connection.connect()
16
+ logger = Logger(logger_connection, logging.INFO, "AdsLogger", "LOGS", "LOGS_details")
17
+ logger.info("Début de la démonstration...")
18
+ logger.disable()
19
+ set_timer(True)
20
+
21
+ # Déclarons une source base de données
22
+ source = dbPgsql({'database':pg_dwh_db
23
+ , 'user':pg_dwh_user
24
+ , 'password':pg_dwh_pwd
25
+ , 'port':pg_dwh_port
26
+ , 'host':pg_dwh_host}, logger, batch_size=1)
27
+
28
+ # Déclarer une destination, c'est un peu plus complexe
29
+ destination = {
30
+ 'name': 'test',
31
+ 'db': dbPgsql({'database':pg_dwh_db, 'user':pg_dwh_user, 'password':pg_dwh_pwd, 'port':pg_dwh_port
32
+ , 'host':pg_dwh_host}, logger),
33
+ 'table': 'demo_pipeline',
34
+ 'cols': ['tenantname', 'taille', 'unite', 'fichier']
35
+ }
36
+
37
+ # Créons la table de réception de nos données
38
+ destination['db'].connect()
39
+ destination['db'].sqlExec(''' DROP TABLE IF EXISTS demo_pipeline; ''')
40
+ destination['db'].sqlExec('''
41
+ CREATE TABLE IF NOT EXISTS demo_pipeline (
42
+ id SERIAL PRIMARY KEY,
43
+ tenantname VARCHAR(255),
44
+ taille FLOAT(8),
45
+ unite VARCHAR(10),
46
+ fichier VARCHAR(255)
47
+ );
48
+ ''')
49
+
50
+ # Voici la requête pour la source
51
+ query = '''
52
+ SELECT tenantname, taille, unite, fichier
53
+ FROM onyx_qs."diskcheck" LIMIT 5
54
+ '''
55
+ logger.enable()
56
+
57
+ # Premier pipeline
58
+ pipeline_1 = pipeline({
59
+ 'db_source': source, # La source du pipeline
60
+ 'query_source': query, # La requête qui sera exécutée sur cette source
61
+ 'db_destinations': destination, # La destination du pipeline
62
+ 'batch_size': 1
63
+ }, logger)
64
+
65
+ rejects = pipeline_1.run() # pipeline.run() renvoie les rejets du pipeline, ce sera une liste vide s'il
66
+ # n'y en a pas
67
+ print(f"{len(rejects)} rejets : {rejects}")
68
+
69
+ # Un batch_size à 1, ce insère les lignes une par une, un batch_size plus grand implique un run plus rapide
70
+ # pour le même nombre de lignes, batch_size est à 10 000 par défaut
71
+ # Second pipeline
72
+ source = dbPgsql({'database':pg_dwh_db
73
+ , 'user':pg_dwh_user
74
+ , 'password':pg_dwh_pwd
75
+ , 'port':pg_dwh_port
76
+ , 'host':pg_dwh_host}, logger)
77
+
78
+ pipeline_2 = pipeline({
79
+ 'db_source': source, # La source du pipeline
80
+ 'query_source': query, # La requête qui sera exécutée sur cette source
81
+ 'db_destinations': destination # La destination du pipeline
82
+ }, logger)
83
+
84
+ rejects = pipeline_2.run()
85
+ print(f"{len(rejects)} rejets : {rejects}")
86
+
87
+
88
+ logger.info("Fin de la démonstration")