Référence
CLI
process-cases-by-dict

csweb:process-cases-by-dict

Description Commande CLI pour effectuer le breakout sélectif des questionnaires CSPro vers la base de données analytique (PostgreSQL/MySQL/SQL Server).

Syntax

docker compose exec csweb php bin/console csweb:process-cases-by-dict \
 dictionnaires=<DICT_NAME>[,<DICT_NAME2>,...] \
 [--threads=<NUMBER>] \
 [--overwrite] \
 [-vvv]

Arguments

dictionnaires (Requis)

Liste de dictionnaires à traiter, séparés par des virgules.

Format :

dictionnaires=DICT_NAME
dictionnaires=DICT1,DICT2,DICT3

Exemples :

# Un seul dictionnaire
dictionnaires=SURVEY_DICT
 
# Plusieurs dictionnaires
dictionnaires=EVAL_DICT,KAIROS_DICT,CENSUS_DICT

Options

--threads=NUMBER Nombre de threads parallèles pour le traitement des questionnaires.

Défaut : 1 Recommandé : 3-5 (selon CPU disponibles) Maximum : 10

Exemples :

# Avec 3 threads
--threads=3
 
# Avec 5 threads (optimal pour serveurs)
--threads=5

Impact sur les performances :

Plus de threads = traitement plus rapide mais consommation CPU plus élevée. Le gain dépend du matériel et du volume de données.

--overwrite

Écraser les tables existantes si elles existent déjà.

Comportement :

  • Sans --overwrite : Erreur si les tables existent déjà
  • Avec --overwrite : Suppression des tables existantes + recréation

Exemples :

# Re-breakout complet (écraser données)
php bin/console csweb:process-cases-by-dict dictionnaires=EVAL_DICT --overwrite
 
# Breakout initial (échouera si tables existent)
php bin/console csweb:process-cases-by-dict dictionnaires=EVAL_DICT

-vvv (Verbosity)

Activer les logs de debug détaillés.

Niveaux de verbosity :

FlagNiveauOutput
(none)NORMALMessages INFO uniquement
-vVERBOSE+ Messages NOTICE
-vvVERY_VERBOSE+ Messages DEBUG
-vvvDEBUGTous les messages + SQL queries

Exemple avec -vvv :

php bin/console csweb:process-cases-by-dict dictionnaires=KAIROS_DICT -vvv

Output attendu :

[INFO] Updating schema tables for Dictionary: KAIROS_DICT
[DEBUG] CSWeb Process Runner creating a new blob breakout thread
[DEBUG] Creating process for dictionary KAIROS_DICT jobID: 1
[DEBUG] Creating process for dictionary KAIROS_DICT jobID: 2
[DEBUG] Creating process for dictionary KAIROS_DICT jobID: 3
[DEBUG] Thread 1: Processing case GUID abc123...
[DEBUG] Thread 2: Processing case GUID def456...
[DEBUG] Thread 3: Processing case GUID ghi789...
[INFO] Processed 1000/50000 cases (2%)
[INFO] Processed 2000/50000 cases (4%)
...
[INFO] Breakout completed: 50000 cases in 00:15:32

Exemples d'Utilisation

Exemple 1: Breakout Simple (1 dictionnaire)

docker compose exec csweb php bin/console csweb:process-cases-by-dict \
 dictionnaires=EVAL_DICT

Résultat :

  • Tables créées : eval_cases, eval_producteurs, eval_observations, etc.
  • Données insérées depuis questionnaires CSPro

Exemple 2: Breakout Multiple (3 dictionnaires)

docker compose exec csweb php bin/console csweb:process-cases-by-dict \
 dictionnaires=SURVEY_DICT,CENSUS_DICT,KAIROS_DICT \
 --threads=5 \
 -vvv

Résultat :

  • Tables survey_* créées
  • Tables census_* créées
  • Tables kairos_* créées
  • 5 threads par dictionnaire

Exemple 3: Re-breakout avec Overwrite

docker compose exec csweb php bin/console csweb:process-cases-by-dict \
 dictionnaires=EVAL_DICT \
 --overwrite \
 --threads=3

Résultat :

  • Tables existantes supprimées
  • Nouvelles tables créées
  • Données ré-insérées depuis CSPro

Exemple 4: Production (gros volume)

docker compose exec csweb php bin/console csweb:process-cases-by-dict \
 dictionnaires=RGPH5_DICT \
 --threads=10 \
 -vvv > /tmp/rgph5_breakout.log 2>&1 &

Résultat :

  • Gain de temps significatif vs breakout global
  • Logs sauvegardés dans /tmp/rgph5_breakout.log
  • Processus en arrière-plan (detached)

Pattern de Nommage des Tables

Règle

Format : {label}_{table_name}

Extraction du label depuis le nom du dictionnaire :

// Exemple: "SURVEY_DICT" -> "survey"
$label = str_replace(" ", "_", str_replace("_DICT", "", $dictionaryName));
$prefix = strtolower($label) . "_";

Exemples

Nom DictionnaireLabelTables Générées
SURVEY_DICTsurveysurvey_cases, survey_level_1, survey_record_001
CENSUS_DICTcensuscensus_cases, census_level_1, census_record_001
KAIROS_DICTkairoskairos_cases, kairos_producteurs, kairos_observations
EVAL_DICTevaleval_cases, eval_producteurs_cases, eval_observations_cases
RGPH5_DICTrgph5rgph5_cases, rgph5_menages, rgph5_individus

Tables Créées Pour chaque dictionnaire, les tables suivantes sont automatiquement créées :

1. Table {label}_cases

Table principale contenant les métadonnées de chaque questionnaire.

Colonnes :

guid VARCHAR(255) PRIMARY KEY -- Identifiant unique du questionnaire
level_id VARCHAR(50) -- Niveau hiérarchique
case_label TEXT -- Label du questionnaire
deleted INT -- Soft delete (0 = actif, 1 = supprimé)
verified INT -- Statut de vérification
partial_save INT -- Sauvegarde partielle
modified_date TIMESTAMP -- Date de dernière modification

2. Tables de Levels Tables pour chaque niveau hiérarchique (ménage, individu, observation, etc.).

Exemple : {label}_level_1

CREATE TABLE kairos_level_1 (
 guid VARCHAR(255) PRIMARY KEY,
 parent_guid VARCHAR(255),
 -- Colonnes spécifiques au niveau 1 --
 FOREIGN KEY (parent_guid) REFERENCES kairos_cases(guid)
);

3. Tables de Records Tables pour chaque record CSPro défini dans le dictionnaire.

Exemple : {label}_producteurs

CREATE TABLE kairos_producteurs (
 guid VARCHAR(255) PRIMARY KEY,
 parent_guid VARCHAR(255),
 producteur_id INT,
 nom TEXT,
 prenom TEXT,
 telephone VARCHAR(20),
 -- Autres colonnes du record --
 FOREIGN KEY (parent_guid) REFERENCES kairos_level_1(guid)
);

Workflow Interne

Étapes du Breakout

1. Lecture du dictionnaire CSPro

2. Génération schéma tables SQL

3. Création tables dans DB breakout

4. Comptage des questionnaires (getDataCounts)

5. Répartition en jobs (1 job par thread)

6. Traitement parallèle:
 - Thread 1 : Cases 1-10000
 - Thread 2 : Cases 10001-20000
 - Thread 3 : Cases 20001-30000

7. Insertion données dans tables

8. Vérification intégrité

Classes PHP Impliquées

ClasseRôle
ProcessCasesByDictCommandCommande CLI Symfony
MySQLDictionarySchemaGeneratorGénération schéma tables
MySQLQuestionnaireSerializerSérialisation questionnaires CSPro
DataSettingsConfiguration connexion DB
MapDataRepositoryRepository accès données

Variables d'Environnement

Breakout DB (Configurable)

# Type de SGBD
BREAKOUT_DB_TYPE=postgresql # ou mysql, sqlserver
 
# PostgreSQL
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DATABASE=csweb_analytics
POSTGRES_USER=csweb_analytics
POSTGRES_PASSWORD=secure_pass
 
# MySQL
MYSQL_BREAKOUT_HOST=mysql-breakout
MYSQL_BREAKOUT_PORT=3307
MYSQL_BREAKOUT_DATABASE=csweb_breakout
MYSQL_BREAKOUT_USER=breakout_user
MYSQL_BREAKOUT_PASSWORD=breakout_pass
 
# SQL Server
SQLSERVER_HOST=sqlserver
SQLSERVER_PORT=1433
SQLSERVER_DATABASE=CSWeb_Analytics
SQLSERVER_USER=sa
SQLSERVER_PASSWORD=YourStrong!Passw0rd

MySQL Metadata (Fixe)

MYSQL_HOST=csweb-mysql
MYSQL_PORT=3306
MYSQL_DATABASE=csweb
MYSQL_USER=csweb
MYSQL_PASSWORD=csweb_pass

Vérification Post-Breakout

1. Vérifier Tables Créées

-- Se connecter à PostgreSQL
docker compose exec postgres psql -U csweb_analytics csweb_analytics
 
-- Lister toutes les tables
\dt
 
-- Output attendu:
-- Schema | Name | Type | Owner
-- --------+---------------------+-------+----------------
-- public | eval_cases | table | csweb_analytics
-- public | eval_producteurs | table | csweb_analytics
-- public | eval_observations | table | csweb_analytics

2. Compter les Lignes

-- PostgreSQL
SELECT COUNT(*) FROM eval_cases;
SELECT COUNT(*) FROM eval_producteurs;
SELECT COUNT(*) FROM eval_observations;
 
-- Vérifier cohérence avec CSWeb
-- Nombre de cases dans eval_cases = nombre de questionnaires uploadés

3. Tester Requête Analytique

-- Exemple: Compter producteurs par région
SELECT region,
 COUNT(*) as nb_producteurs
FROM eval_producteurs
GROUP BY region
ORDER BY nb_producteurs DESC;

Troubleshooting

Erreur: Table Already Exists

Symptôme :

SQLSTATE[42P07]: Relation already exists: 7 ERROR: relation "eval_cases" already exists

Cause : Les tables existent déjà dans la base de données.

Solutions :

  1. Utiliser --overwrite pour écraser :
php bin/console csweb:process-cases-by-dict dictionnaires=EVAL_DICT --overwrite
  1. Supprimer manuellement :
-- PostgreSQL
DROP TABLE IF EXISTS eval_cases CASCADE;
DROP TABLE IF EXISTS eval_producteurs CASCADE;
-- etc.

Erreur: Dictionary Not Found

Symptôme :

Dictionary "SURVEY_DICT" not found in CSWeb

Causes :

  • Nom du dictionnaire mal écrit (case-sensitive)
  • Dictionnaire pas uploadé dans CSWeb
  • Dictionnaire supprimé

Solutions :

  1. Vérifier dictionnaires disponibles :
# Via MySQL metadata
docker compose exec csweb-mysql mysql -u csweb -p csweb SELECT name, label FROM cspro_dictionaries;
  1. Uploader dictionnaire dans CSWeb UI :
  • Administration Dictionaries Upload

Erreur: Connection Refused

Symptôme :

SQLSTATE[HY000] [2002] Connection refused

Cause : Base de données breakout pas démarrée.

Solutions :

# Vérifier containers actifs
docker compose ps
 
# Démarrer container manquant
docker compose up -d postgres # ou mysql-breakout, sqlserver

Erreur: Out of Memory

Symptôme :

PHP Fatal error: Allowed memory size of 134217728 bytes exhausted

Cause : Breakout de gros dictionnaires (millions de cas).

Solution :

# Augmenter memory limit PHP
docker compose exec csweb php -d memory_limit=2G bin/console \
 csweb:process-cases-by-dict dictionnaires=RGPH5_DICT --threads=10

Erreur: Wrong Database Type

Symptôme :

SQLSTATE[HY000]: Driver not found for pdo_sqlsrv

Cause : BREAKOUT_DB_TYPE ne correspond pas aux variables configurées.

Solution :

# Vérifier cohérence .env
BREAKOUT_DB_TYPE=sqlserver # Doit correspondre
SQLSERVER_HOST=... # Variables SQL Server doivent être remplies

Logs

Logs de la Commande

# Logs Symfony
tail -f var/logs/dev.log
 
# Logs de la console command avec -vvv
php bin/console csweb:process-cases-by-dict dictionnaires=KAIROS_DICT -vvv

Logs de la Base de Données

# Logs PostgreSQL
sudo tail -f /var/log/postgresql/postgresql-14-main.log
 
# Activer query logging (postgresql.conf)
log_statement = 'all'

Performance

Performance

Le breakout sélectif par dictionnaire est significativement plus rapide que le breakout global, car il traite un seul dictionnaire à la fois au lieu de tous séquentiellement.

Facteurs de performance :

  • Volume de données (nombre de cas et complexité du dictionnaire)
  • Driver SGBD (PostgreSQL, MySQL, SQL Server)
  • Matériel serveur (CPU, RAM, disque)
  • Réseau (mode remote)

Le breakout sélectif a été validé en production lors du RGPH5 Sénégal avec des gains de performance significatifs.

Ressources


CSWeb Community Platform v2.0 - CLI Reference Innovation : Assietou DIAGNE (ANSD, Sénégal) | Intégration : Bouna DRAME