ajout de la syncho pour Enum.md avec init.sql
This commit is contained in:
parent
3c5d53e48d
commit
55d4b4ff85
44
README.md
44
README.md
@ -58,10 +58,24 @@ Ouvre ton navigateur sur :
|
|||||||
http://localhost:8081
|
http://localhost:8081
|
||||||
```
|
```
|
||||||
|
|
||||||
**Email** : `admin@ptits-pas.fr`
|
Par défaut un administrateur est créé par la migration d'initialisation (`migrations/01_init.sql`).
|
||||||
**Mot de passe** : `admin123`
|
Pour des raisons de sécurité, le mot de passe n'est pas gardé en clair dans le README.
|
||||||
|
|
||||||
**Mot de passse pour se connecter au server local** : `admin123`
|
Si tu veux un mot de passe connu en dev, génère le hash bcrypt puis modifie la migration
|
||||||
|
ou crée un seed SQL :
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Exemple pour définir le mot de passe en dev :
|
||||||
|
UPDATE utilisateurs
|
||||||
|
SET password = crypt('admin123', gen_salt('bf'))
|
||||||
|
WHERE email = 'admin@ptits-pas.fr';
|
||||||
|
```
|
||||||
|
|
||||||
|
Exécute la commande suivante pour appliquer ce seed sur ta base dev :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -i ptitspas-postgres-standalone psql -U admin -d ptitpas_db -c "UPDATE utilisateurs SET password = crypt('admin123', gen_salt('bf')) WHERE email = 'admin@ptits-pas.fr';"
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Conseils et bonnes pratiques
|
## Conseils et bonnes pratiques
|
||||||
@ -71,6 +85,30 @@ http://localhost:8081
|
|||||||
- Pour ajouter des scripts d'automatisation, crée un dossier `scripts/`
|
- Pour ajouter des scripts d'automatisation, crée un dossier `scripts/`
|
||||||
- Documente les étapes spécifiques dans le README ou dans `docs/`
|
- Documente les étapes spécifiques dans le README ou dans `docs/`
|
||||||
|
|
||||||
|
### Synchroniser les types ENUM avec les CSV d'import
|
||||||
|
|
||||||
|
Un utilitaire est fourni pour générer une migration sûre qui ajoute les valeurs
|
||||||
|
manquantes aux types ENUM en base en se basant sur les CSV présents dans
|
||||||
|
`bdd/data_test/`.
|
||||||
|
|
||||||
|
Générer la migration :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make sync-enums
|
||||||
|
```
|
||||||
|
|
||||||
|
Le fichier généré est `migrations/00_sync_enums.sql`. Relis ce fichier avant de
|
||||||
|
l'appliquer (il contient des blocs `DO $$ ... ALTER TYPE ... ADD VALUE` qui
|
||||||
|
ne suppriment rien mais modifient le type ENUM). Pour appliquer la migration
|
||||||
|
sur ta base locale :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Après avoir démarré la base (make reset ou make demo)
|
||||||
|
docker exec -i ptitspas-postgres-standalone psql -U admin -d ptitpas_db -f migrations/00_sync_enums.sql
|
||||||
|
```
|
||||||
|
|
||||||
|
Attention : ne pas appliquer directement en production sans vérification.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Contact
|
## Contact
|
||||||
|
|||||||
@ -14,7 +14,8 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "5433:5432"
|
- "5433:5432"
|
||||||
volumes:
|
volumes:
|
||||||
# Scripts de migration (ordre important → init, indexes, checks, triggers, import…)
|
# Scripts de migration (ordre important → sync_enums, init, indexes, checks, triggers, import…)
|
||||||
|
- ./migrations/00_sync_enums.sql:/docker-entrypoint-initdb.d/00_sync_enums.sql
|
||||||
- ./migrations/01_init.sql:/docker-entrypoint-initdb.d/01_init.sql
|
- ./migrations/01_init.sql:/docker-entrypoint-initdb.d/01_init.sql
|
||||||
- ./migrations/02_indexes.sql:/docker-entrypoint-initdb.d/02_indexes.sql
|
- ./migrations/02_indexes.sql:/docker-entrypoint-initdb.d/02_indexes.sql
|
||||||
- ./migrations/03_checks.sql:/docker-entrypoint-initdb.d/03_checks.sql
|
- ./migrations/03_checks.sql:/docker-entrypoint-initdb.d/03_checks.sql
|
||||||
|
|||||||
8
makefile
8
makefile
@ -69,4 +69,10 @@ psql:
|
|||||||
|
|
||||||
stop:
|
stop:
|
||||||
docker compose -f docker-compose.dev.yml down
|
docker compose -f docker-compose.dev.yml down
|
||||||
j
|
stop:
|
||||||
|
docker compose -f docker-compose.dev.yml down
|
||||||
|
|
||||||
|
sync-enums:
|
||||||
|
@echo "🔁 Génération de migrations/00_sync_enums.sql depuis les CSV"
|
||||||
|
@python3 scripts/sync_enums.py > migrations/00_sync_enums.sql
|
||||||
|
@echo "✅ migrations/00_sync_enums.sql générée. Relis le fichier avant de l'appliquer."
|
||||||
183
migrations/00_sync_enums.sql
Normal file
183
migrations/00_sync_enums.sql
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
-- Generated by scripts/sync_enums.py — review before applying
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_contrat_type'
|
||||||
|
AND e.enumlabel = 'brouillon'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_contrat_type ADD VALUE 'brouillon';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_dossier_type'
|
||||||
|
AND e.enumlabel = 'envoye'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_dossier_type ADD VALUE 'envoye';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_enfant_type'
|
||||||
|
AND e.enumlabel = 'actif'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_enfant_type ADD VALUE 'actif';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_enfant_type'
|
||||||
|
AND e.enumlabel = 'scolarise'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_enfant_type ADD VALUE 'scolarise';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'genre_type'
|
||||||
|
AND e.enumlabel = 'F'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE genre_type ADD VALUE 'F';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'genre_type'
|
||||||
|
AND e.enumlabel = 'H'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE genre_type ADD VALUE 'H';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'type_evenement_type'
|
||||||
|
AND e.enumlabel = 'absence_enfant'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE type_evenement_type ADD VALUE 'absence_enfant';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_evenement_type'
|
||||||
|
AND e.enumlabel = 'propose'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_evenement_type ADD VALUE 'propose';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'role_type'
|
||||||
|
AND e.enumlabel = 'administrateur'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE role_type ADD VALUE 'administrateur';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'role_type'
|
||||||
|
AND e.enumlabel = 'assistante_maternelle'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE role_type ADD VALUE 'assistante_maternelle';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'role_type'
|
||||||
|
AND e.enumlabel = 'gestionnaire'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE role_type ADD VALUE 'gestionnaire';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'role_type'
|
||||||
|
AND e.enumlabel = 'parent'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE role_type ADD VALUE 'parent';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_utilisateur_type'
|
||||||
|
AND e.enumlabel = 'actif'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_utilisateur_type ADD VALUE 'actif';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = 'statut_validation_type'
|
||||||
|
AND e.enumlabel = 'valide'
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE statut_validation_type ADD VALUE 'valide';
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
|
||||||
@ -262,7 +262,10 @@ INSERT INTO utilisateurs (
|
|||||||
VALUES (
|
VALUES (
|
||||||
gen_random_uuid(),
|
gen_random_uuid(),
|
||||||
'admin@ptits-pas.fr',
|
'admin@ptits-pas.fr',
|
||||||
'admin123', -- ⚠️ à remplacer par le hash réel du mot de passe
|
-- Use a bcrypt hash via pgcrypto for the default admin password in dev.
|
||||||
|
-- In dev you can keep a known password by using: crypt('admin123', gen_salt('bf'))
|
||||||
|
-- For security, avoid committing plaintext passwords in migrations for production.
|
||||||
|
crypt('admin123', gen_salt('bf')),
|
||||||
'Admin',
|
'Admin',
|
||||||
'PtitsPas',
|
'PtitsPas',
|
||||||
'super_admin',
|
'super_admin',
|
||||||
|
|||||||
100
scripts/sync_enums.py
Normal file
100
scripts/sync_enums.py
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
scripts/sync_enums.py
|
||||||
|
|
||||||
|
Génère une migration SQL non destructive pour ajouter les valeurs d'ENUM
|
||||||
|
manquantes en se basant sur les CSV de `bdd/data_test`.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
python3 scripts/sync_enums.py > migrations/00_sync_enums.sql
|
||||||
|
|
||||||
|
Relire le SQL généré avant application en production.
|
||||||
|
"""
|
||||||
|
from pathlib import Path
|
||||||
|
import csv
|
||||||
|
from collections import defaultdict
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Mapping colonne CSV -> nom du type enum en base
|
||||||
|
# NOTE: mapping is now based on filename (more precise)
|
||||||
|
CSV_DIR = Path('bdd/data_test')
|
||||||
|
|
||||||
|
# Define per-file mappings: filename stem -> {column_name: enum_type}
|
||||||
|
FILE_COLUMN_ENUM_MAP = {
|
||||||
|
'utilisateurs': {
|
||||||
|
'role': 'role_type',
|
||||||
|
'genre': 'genre_type',
|
||||||
|
'statut': 'statut_utilisateur_type',
|
||||||
|
},
|
||||||
|
'enfants': {
|
||||||
|
'statut': 'statut_enfant_type',
|
||||||
|
'genre': 'genre_type',
|
||||||
|
},
|
||||||
|
'contrats': {
|
||||||
|
'statut': 'statut_contrat_type',
|
||||||
|
},
|
||||||
|
'dossiers': {
|
||||||
|
'statut': 'statut_dossier_type',
|
||||||
|
},
|
||||||
|
'evenements': {
|
||||||
|
'type': 'type_evenement_type',
|
||||||
|
'statut': 'statut_evenement_type',
|
||||||
|
},
|
||||||
|
'validations': {
|
||||||
|
'statut': 'statut_validation_type',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def quote_sql_literal(s: str) -> str:
|
||||||
|
return "'" + s.replace("'", "''") + "'"
|
||||||
|
|
||||||
|
def discover_values():
|
||||||
|
# heuristique : map common column names to enums
|
||||||
|
enum_values = defaultdict(set)
|
||||||
|
for p in sorted(CSV_DIR.glob('*.csv')):
|
||||||
|
try:
|
||||||
|
with p.open(newline='', encoding='utf-8') as fh:
|
||||||
|
reader = csv.DictReader(fh)
|
||||||
|
fname = p.stem
|
||||||
|
per_file_map = FILE_COLUMN_ENUM_MAP.get(fname, {})
|
||||||
|
for row in reader:
|
||||||
|
for col, enum in per_file_map.items():
|
||||||
|
if col in row and row[col] is not None:
|
||||||
|
v = row[col].strip()
|
||||||
|
if v != '':
|
||||||
|
enum_values[enum].add(v)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"-- Error reading {p}: {e}", file=sys.stderr)
|
||||||
|
return enum_values
|
||||||
|
|
||||||
|
def emit_sql(enum_values):
|
||||||
|
lines = []
|
||||||
|
lines.append('-- Generated by scripts/sync_enums.py — review before applying')
|
||||||
|
for enum_type, vals in enum_values.items():
|
||||||
|
if not vals:
|
||||||
|
continue
|
||||||
|
for v in sorted(vals):
|
||||||
|
lit = quote_sql_literal(v)
|
||||||
|
block = f"""
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF NOT EXISTS (
|
||||||
|
SELECT 1 FROM pg_enum e
|
||||||
|
JOIN pg_type t ON e.enumtypid = t.oid
|
||||||
|
WHERE t.typname = {quote_sql_literal(enum_type)}
|
||||||
|
AND e.enumlabel = {lit}
|
||||||
|
) THEN
|
||||||
|
ALTER TYPE {enum_type} ADD VALUE {lit};
|
||||||
|
END IF;
|
||||||
|
END$$;
|
||||||
|
"""
|
||||||
|
lines.append(block)
|
||||||
|
return '\n'.join(lines)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
enum_values = discover_values()
|
||||||
|
sql = emit_sql(enum_values)
|
||||||
|
print(sql)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
38
verify.log
38
verify.log
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
executed_at
|
executed_at
|
||||||
-------------------------------
|
-------------------------------
|
||||||
2025-09-19 08:16:02.305781+00
|
2025-09-19 09:15:01.473058+00
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
=== 1) Comptes & répartition par rôle ==========================
|
=== 1) Comptes & répartition par rôle ==========================
|
||||||
@ -126,49 +126,49 @@
|
|||||||
=== 13) Performance : EXPLAIN sur requêtes clés ===============
|
=== 13) Performance : EXPLAIN sur requêtes clés ===============
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Limit (cost=11.31..11.31 rows=3 width=89) (actual time=0.027..0.029 rows=0 loops=1)
|
Limit (cost=11.31..11.31 rows=3 width=89) (actual time=0.035..0.036 rows=0 loops=1)
|
||||||
-> Sort (cost=11.31..11.31 rows=3 width=89) (actual time=0.026..0.027 rows=0 loops=1)
|
-> Sort (cost=11.31..11.31 rows=3 width=89) (actual time=0.032..0.033 rows=0 loops=1)
|
||||||
Sort Key: cree_le DESC
|
Sort Key: cree_le DESC
|
||||||
Sort Method: quicksort Memory: 25kB
|
Sort Method: quicksort Memory: 25kB
|
||||||
-> Bitmap Heap Scan on messages m (cost=4.17..11.28 rows=3 width=89) (actual time=0.021..0.021 rows=0 loops=1)
|
-> Bitmap Heap Scan on messages m (cost=4.17..11.28 rows=3 width=89) (actual time=0.023..0.024 rows=0 loops=1)
|
||||||
Recheck Cond: (id_dossier = 'dddddddd-dddd-dddd-dddd-dddddddddddd'::uuid)
|
Recheck Cond: (id_dossier = 'dddddddd-dddd-dddd-dddd-dddddddddddd'::uuid)
|
||||||
-> Bitmap Index Scan on idx_messages_id_dossier_cree_le (cost=0.00..4.17 rows=3 width=0) (actual time=0.011..0.011 rows=0 loops=1)
|
-> Bitmap Index Scan on idx_messages_id_dossier_cree_le (cost=0.00..4.17 rows=3 width=0) (actual time=0.012..0.013 rows=0 loops=1)
|
||||||
Index Cond: (id_dossier = 'dddddddd-dddd-dddd-dddd-dddddddddddd'::uuid)
|
Index Cond: (id_dossier = 'dddddddd-dddd-dddd-dddd-dddddddddddd'::uuid)
|
||||||
Planning Time: 0.837 ms
|
Planning Time: 1.468 ms
|
||||||
Execution Time: 0.079 ms
|
Execution Time: 0.521 ms
|
||||||
(10 rows)
|
(10 rows)
|
||||||
|
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Index Scan using idx_evenements_id_enfant_date_debut on evenements ev (cost=0.15..8.17 rows=1 width=161) (actual time=0.006..0.007 rows=0 loops=1)
|
Index Scan using idx_evenements_id_enfant_date_debut on evenements ev (cost=0.15..8.17 rows=1 width=161) (actual time=0.006..0.007 rows=0 loops=1)
|
||||||
Index Cond: ((id_enfant = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid) AND (date_debut >= '2025-01-01 00:00:00+00'::timestamp with time zone))
|
Index Cond: ((id_enfant = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid) AND (date_debut >= '2025-01-01 00:00:00+00'::timestamp with time zone))
|
||||||
Planning Time: 0.107 ms
|
Planning Time: 0.117 ms
|
||||||
Execution Time: 0.099 ms
|
Execution Time: 0.025 ms
|
||||||
(4 rows)
|
(4 rows)
|
||||||
|
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
------------------------------------------------------------------------------------------------------------------------------------------------------
|
------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Limit (cost=9.52..9.53 rows=2 width=73) (actual time=0.020..0.021 rows=0 loops=1)
|
Limit (cost=9.52..9.53 rows=2 width=73) (actual time=0.012..0.013 rows=0 loops=1)
|
||||||
-> Sort (cost=9.52..9.53 rows=2 width=73) (actual time=0.019..0.020 rows=0 loops=1)
|
-> Sort (cost=9.52..9.53 rows=2 width=73) (actual time=0.011..0.012 rows=0 loops=1)
|
||||||
Sort Key: cree_le DESC
|
Sort Key: cree_le DESC
|
||||||
Sort Method: quicksort Memory: 25kB
|
Sort Method: quicksort Memory: 25kB
|
||||||
-> Bitmap Heap Scan on notifications n (cost=4.17..9.51 rows=2 width=73) (actual time=0.014..0.014 rows=0 loops=1)
|
-> Bitmap Heap Scan on notifications n (cost=4.17..9.51 rows=2 width=73) (actual time=0.007..0.008 rows=0 loops=1)
|
||||||
Recheck Cond: ((id_utilisateur = '33333333-3333-3333-3333-333333333333'::uuid) AND (NOT lu))
|
Recheck Cond: ((id_utilisateur = '33333333-3333-3333-3333-333333333333'::uuid) AND (NOT lu))
|
||||||
-> Bitmap Index Scan on idx_notifications_user_lu_cree_le (cost=0.00..4.17 rows=2 width=0) (actual time=0.008..0.008 rows=0 loops=1)
|
-> Bitmap Index Scan on idx_notifications_user_lu_cree_le (cost=0.00..4.17 rows=2 width=0) (actual time=0.004..0.005 rows=0 loops=1)
|
||||||
Index Cond: ((id_utilisateur = '33333333-3333-3333-3333-333333333333'::uuid) AND (lu = false))
|
Index Cond: ((id_utilisateur = '33333333-3333-3333-3333-333333333333'::uuid) AND (lu = false))
|
||||||
Planning Time: 0.122 ms
|
Planning Time: 0.087 ms
|
||||||
Execution Time: 0.043 ms
|
Execution Time: 0.027 ms
|
||||||
(10 rows)
|
(10 rows)
|
||||||
|
|
||||||
QUERY PLAN
|
QUERY PLAN
|
||||||
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
Sort (cost=8.18..8.18 rows=1 width=267) (actual time=0.429..0.431 rows=0 loops=1)
|
Sort (cost=8.18..8.18 rows=1 width=267) (actual time=0.017..0.018 rows=0 loops=1)
|
||||||
Sort Key: cree_le DESC
|
Sort Key: cree_le DESC
|
||||||
Sort Method: quicksort Memory: 25kB
|
Sort Method: quicksort Memory: 25kB
|
||||||
-> Index Scan using idx_dossiers_id_parent_enfant_statut_cree_le on dossiers d (cost=0.15..8.17 rows=1 width=267) (actual time=0.419..0.419 rows=0 loops=1)
|
-> Index Scan using idx_dossiers_id_parent_enfant_statut_cree_le on dossiers d (cost=0.15..8.17 rows=1 width=267) (actual time=0.012..0.012 rows=0 loops=1)
|
||||||
Index Cond: ((id_parent = '33333333-3333-3333-3333-333333333333'::uuid) AND (id_enfant = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid))
|
Index Cond: ((id_parent = '33333333-3333-3333-3333-333333333333'::uuid) AND (id_enfant = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa'::uuid))
|
||||||
Planning Time: 1.115 ms
|
Planning Time: 0.062 ms
|
||||||
Execution Time: 0.476 ms
|
Execution Time: 0.032 ms
|
||||||
(7 rows)
|
(7 rows)
|
||||||
|
|
||||||
=== 14) JSONB : exemples de filtrage ===========================
|
=== 14) JSONB : exemples de filtrage ===========================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user