Architecture technique - PT0CE¶
Table des matières¶
- Structure modulaire
- Flux de données
- Gestion des tables
- Stratégies d'optimisation
- Gestion des erreurs
- Configuration
Structure modulaire¶
Organisation des modules¶
pt0ce_main.py
├── extract_pas_prb.py
├── extract_master_data.py
│ └── utils/data_validator.py
├── compute_price_cubes.py
│ └── utils/cube_calculator.py
├── price_sensitivity.py
├── create_corridor_history.py
├── business_rules.py
└── config/pt0ce_config.py
└── utils/period_manager.py
Responsabilités des modules¶
pt0ce_main.py¶
- Orchestration du workflow complet
- Gestion des arguments ligne de commande
- Coordination des phases d'exécution
- Nettoyage des tables temporaires
extract_pas_prb.py¶
- Extraction de l'historique PAS jour par jour
- Extraction des PAS/PRB actifs
- Création des tables
PT0CE_PAS_PRB_*
extract_master_data.py¶
- Chargement des mappings CSV
- Enrichissement des transactions
- Calcul de la marge nette
- Création de
PT0CE_MASTER_DATA_*
compute_price_cubes.py¶
- Calcul des cubes MASTER et NATIONAL
- Pré-calcul des statistiques par niveau
- Délégation du calcul des corridors
utils/cube_calculator.py¶
- Logique de remontée hiérarchique
- Calcul des bornes PL1-PLX
- Application des contraintes
- Gestion du keep-alive Oracle
price_sensitivity.py¶
- Analyse fréquence/ventes
- Classification F1/F2 × S1/S2
- Attribution sensibilité HIGH/MEDIUM/LOW
create_corridor_history.py¶
- Fusion corridors + sensibilité
- Création tables finales
- Génération statistiques
business_rules.py¶
- Règles de détermination des univers
- Filtres standards
- Matrice de sensibilité
Flux de données¶
Vue d'ensemble¶
graph TD
A[CSV Files] -->|Validation| B[Tables de mapping]
C[SYS Tables] -->|Extraction| D[PAS History]
C -->|Extraction| E[Master Data]
B -->|Enrichissement| E
D -->|Jointure| E
E -->|Agrégation| F[Cubes MASTER]
E -->|Agrégation| G[Cubes NATIONAL]
F -->|Remontée| H[Corridors]
G -->|Direct| H
H -->|Fusion| I[Sensitivity]
I -->|Merge| J[CORRIDOR_HISTORY]
Phase 1 : Extraction PAS/PRB¶
# Historique jour par jour
WITH DATE_RANGE AS (
SELECT start_date + LEVEL - 1 AS BUSINESS_DATE
FROM DUAL
CONNECT BY LEVEL <= end_date - start_date + 1
)
# Jointure avec SYS_MD_CONDITION pour chaque jour
Phase 2 : Enrichissement Master Data¶
# 1. Chargement mappings CSV → Oracle
PT0CE_TYPE_CLIENT_MAPPING (rechargée)
PT0CE_TYPE_RESTAURANT_MAPPING (rechargée)
# 2. Enrichissement transactions
- Jointure avec mappings
- Calcul UNIVERS selon règles
- Calcul marge nette avec PAS historique
# 3. Création DIMENSION_MAPPING
- Combinaisons uniques avec MT_CAB > 0
- Pour export SAP dans PT1CE
Phase 3 : Calcul des cubes¶
# Pour chaque univers :
1. Cubes MASTER
- Group by dimensions
- Calcul statistiques si ≥ 30 marges distinctes
2. Cubes NATIONAL
- Group by ID_ART uniquement
- Statistiques toutes transactions confondues
Phase 4 : Calcul des corridors¶
# 1. Pré-calcul statistiques par niveau
grouped_by_level = {
0: {'dims': ['ID_ART', 'TYPE_CLIENT', ...], 'stats': {...}},
1: {'dims': ['ID_ART', 'TYPE_CLIENT'], 'stats': {...}},
...
}
# 2. Pour chaque cube
if cube_type == 'NATIONAL':
SOURCE_LEVEL = -1
else:
# Recherche dans la hiérarchie
for level in range(0, max_levels):
if stats_found and distinct_margins >= 30:
SOURCE_LEVEL = level + 1
break
Phase 5 : Analyse sensibilité¶
# Par cube MASTER uniquement
1. Calcul métriques article
- Nombre commandes
- CA total
2. Classification fréquence
- Top 25% → F1
3. Classification Pareto
- Cumul jusqu'à 70% CA → S1
4. Attribution sensibilité
- Matrice F×S → HIGH/MEDIUM/LOW
Gestion des tables¶
Tables temporaires¶
Format : PT0CE_[TYPE]_[UNIVERS]_YYYYMMDD
Caractéristiques :
- COMPRESS NOLOGGING pour performance
- Suppression automatique en fin de traitement
- Index sur colonnes clés
Tables permanentes de référence¶
-- Rechargées à chaque run depuis CSV
PT0CE_TYPE_CLIENT_MAPPING
PT0CE_TYPE_RESTAURANT_MAPPING
-- Structure exemple
CREATE TABLE PT0CE_TYPE_CLIENT_MAPPING (
TYPE_CLIENT VARCHAR2(100),
UNIVERS VARCHAR2(10),
ID_TC_CG VARCHAR2(10),
ID_TC_CIBLE VARCHAR2(10),
FG_HM VARCHAR2(1),
PRB NUMBER(1)
)
Table de mapping dimensions¶
-- Conservée pour PT1CE
PT0CE_DIMENSION_MAPPING_YYYYMMDD
-- Contient uniquement combinaisons avec CA > 0
ID_ART × UNIVERS × TYPE_CLIENT × TYPE_RESTAURANT × GEO
→ ID_TC_CIBLE, ID_SFC_CIBLE, ID_RGC_GRV_SAP
Tables finales¶
PT0CE_CORRIDOR_HISTORY_ZOOM1
PT0CE_CORRIDOR_HISTORY_ZOOM2
PT0CE_CORRIDOR_HISTORY_ZOOM3
-- Remplacées à chaque run
-- Contiennent corridors + sensibilité + métadonnées
Stratégies d'optimisation¶
Performance Oracle¶
Parallélisation¶
Insertion par batch¶
batch_size = 5_000_000
for i in range(0, total_rows, batch_size):
batch_data = data_tuples[i:i+batch_size]
q.execute(params=batch_data, batch_errors=True)
if i % 10_000_000 == 0:
db.commit()
Keep-alive connexion¶
# Pendant les longs calculs
if current_time - last_ping > timedelta(minutes=2):
q = db.create_query("SELECT 1 FROM DUAL")
q.read_value()
q.close()
Optimisation mémoire¶
Pré-calcul et mise en cache¶
# Au lieu de recalculer pour chaque cube
grouped_data = precompute_statistics_by_level()
# Réutilisation pour tous les cubes
for cube in cubes:
stats = lookup_in_grouped_data(cube, grouped_data)
Libération mémoire¶
Traitement vectorisé¶
# Calcul des bornes en masse avec numpy
valid_mask = (pas_actif > 0) & (percentiles < 1)
calculated_prices = np.where(
valid_mask,
pas_actif / (1 - percentiles),
np.nan
)
Réduction de volumétrie¶
Cubes NATIONAL vs hypothétiques¶
- Avant : Produit cartésien complet (millions de cubes)
- Maintenant : 1 cube NATIONAL par article
- Réduction : 10-100x moins de cubes
Filtrage précoce¶
-- Exclusion dès l'extraction
AND NOT (TYPE_CLIENT = 'Hors référentiel'
OR TYPE_RESTAURANT = 'Hors référentiel')
Gestion des erreurs¶
Validation des inputs¶
class DataValidator:
def validate_input_files(self):
# Vérification existence CSV
# Validation colonnes requises
# Contrôle format PRB (1 ou 2)
# Standardisation FG_HM
Gestion des cas limites¶
# Division par zéro
if percentile >= 1:
# Borne non calculable
return np.nan
# PAS manquant
if pas_actif is None or pas_actif <= 0:
# Skip calcul bornes
Logging structuré¶
app.log.info(f"Phase 1: {description}")
app.log.debug(f" Détail: {metrics}")
app.log.warning(f"⚠️ Attention: {issue}")
app.log.error(f"❌ Erreur: {error}")
Configuration¶
Fichier pt0ce_config.json¶
{
"processing": {
"min_distinct_margins": 30,
"parallel_degree": 8,
"batch_size": 100000
},
"price_sensitivity": {
"frequency_threshold": 0.25,
"sales_threshold": 0.70,
"sensitivity_matrix": {
"F1_S1": "HIGH",
"F1_S2": "MEDIUM",
"F2_S1": "MEDIUM",
"F2_S2": "LOW"
}
},
"universes": {
"ZOOM1": {"has_geo": true, "levels": 3},
"ZOOM2": {"has_geo": true, "levels": 3},
"ZOOM3": {"has_geo": false, "levels": 2}
}
}
Surcharge par arguments¶
# Ligne de commande prioritaire
if app.args.min_distinct_margins:
config['min_distinct_margins'] = app.args.min_distinct_margins
Points de configuration¶
- Seuils ajustables sans modification code
- Matrice sensibilité paramétrable
- Chemins fichiers CSV configurables