Démarrage rapide¶
Ce guide vous montre la façon la plus rapide de charger un fichier DDI dans une base de données graphe. Nous commençons avec Neo4j — la configuration la plus courante — puis montrons les autres options.
Si vous n'avez pas encore installé ddigraph, commencez par Installation.
Étape 1 — Choisissez votre base de données¶
Choisissez la base de données que vous voulez utiliser. Si vous n'êtes pas sûr, choisissez Neo4j — c'est l'option la plus complète et la plus facile pour débuter.
Qu'est-ce que c'est ? Neo4j est une base de données graphe qui stocke les données sous forme de nœuds et de relations. C'est le choix recommandé pour la plupart des utilisateurs.
# Démarrer Neo4j avec Docker (une seule fois)
docker run -d --name neo4j \
-p 7474:7474 -p 7687:7687 \
-e NEO4J_AUTH=neo4j/password \
neo4j:latest
# Indiquer à ddigraph où se trouve Neo4j
export DDIGRAPH_NEO4J_URI=bolt://localhost:7687
export DDIGRAPH_NEO4J_USER=neo4j
export DDIGRAPH_NEO4J_PASSWORD=password
# Initialiser le schéma de la base (une seule fois avant le premier chargement)
ddigraph bootstrap
# Charger votre fichier DDI
ddigraph load survey.xml --dataset-id demo
Après l'exécution, vos métadonnées DDI se trouvent dans Neo4j sous forme de graphe.
Ouvrez http://localhost:7474 dans votre navigateur pour l'explorer visuellement.
Que fait bootstrap ?
Il crée les index et contraintes dont Neo4j a besoin pour stocker correctement les
données DDI. C'est sûr de l'exécuter plusieurs fois — si le schéma existe déjà, rien
ne change.
Qu'est-ce que c'est ? RDF (Resource Description Framework) est un format pour représenter les données sous forme de triplets liés. Utilisez ceci si vous travaillez avec des outils du web sémantique ou des triplestores comme Virtuoso, GraphDB ou Stardog.
from rdflib import Graph, Namespace, Literal, URIRef
from rdflib.namespace import RDF, RDFS
from ddigraph import DDIFragmentParser
DDI = Namespace("http://ddi.example.org/")
g = Graph()
g.bind("ddi", DDI)
parser = DDIFragmentParser()
for fragment in parser.parse("survey.xml"):
subj = DDI[fragment.fragment_id]
g.add((subj, RDF.type, DDI[fragment.element_type]))
if fragment.label:
g.add((subj, RDFS.label, Literal(fragment.label)))
# Sauvegarder dans un fichier Turtle
g.serialize("output.ttl", format="turtle")
Qu'est-ce que c'est ? NetworkX est une bibliothèque Python pour analyser des graphes en mémoire — aucune base de données séparée requise. Utilisez ceci pour des analyses locales rapides ou du prototypage.
import networkx as nx
from ddigraph import DDIFragmentParser
G = nx.MultiDiGraph()
parser = DDIFragmentParser()
for fragment in parser.parse("survey.xml"):
G.add_node(fragment.fragment_id,
label=fragment.element_type,
**fragment.to_dict())
for rel_type, ref in fragment.references:
G.add_edge(fragment.fragment_id, ref.id, key=rel_type)
print(f"Chargé : {G.number_of_nodes()} nœuds, {G.number_of_edges()} arêtes")
Qu'est-ce que c'est ? Gremlin est un langage de requête graphe pris en charge par des bases de données comme JanusGraph, Amazon Neptune et Azure Cosmos DB.
from gremlin_python.process.anonymous_traversal import traversal
from gremlin_python.driver.driver_remote_connection import DriverRemoteConnection
from ddigraph import DDIFragmentParser
connection = DriverRemoteConnection('ws://localhost:8182/gremlin', 'g')
g = traversal().withRemote(connection)
parser = DDIFragmentParser()
for fragment in parser.parse("survey.xml"):
g.addV(fragment.element_type) \
.property('id', fragment.fragment_id) \
.property('label', fragment.label or '') \
.iterate()
connection.close()
Étape 2 — Vérifier le format (optionnel)¶
ddigraph détecte automatiquement si votre fichier est DDI Codebook, DDI Lifecycle ou DDI-CDI. Vous pouvez vérifier manuellement avec :
from ddigraph import detect_ddi_format
format_type = detect_ddi_format("survey.xml")
print(format_type) # "codebook", "lifecycle" ou "cdi"
Que signifient ces formats ?
| Format | Élément XML racine | À utiliser quand |
|---|---|---|
codebook |
<codeBook> ou <codebook> |
Archives d'enquêtes traditionnelles |
lifecycle |
<FragmentInstance> |
Outils de conception de questionnaires (DDI-L 3.2 / 3.3) |
cdi |
Espace de noms DDI-CDI | Projets d'intégration inter-domaines |
Si vous n'êtes pas sûr du format de votre fichier, exécutez detect_ddi_format et il vous
le dira.
Étape 3 — Charger depuis Python¶
L'API Python reflète la CLI. Un seul appel charge un fichier. Il détecte le format, initialise le schéma et écrit vers votre cible :
import ddigraph
result = ddigraph.load(
"survey.xml",
target="neo4j://localhost:7687",
dataset_id="my-survey",
)
print(result.flavor, result.nodes_written, result.relationships_written)
target est une URL Neo4j (bolt://... ou neo4j://...). Omettez-la
pour utiliser la connexion de votre environnement. Il existe aussi une
forme asynchrone, ddigraph.aload(...), avec les mêmes arguments.
Pour les autres backends (RDF, Gremlin, NetworkX, pandas), utilisez le
parseur plus un adaptateur — voir les pages
Backends et les exemples par backend
ci-dessus.
Détecter le format d'un fichier sans le charger :
import ddigraph
print(ddigraph.detect("survey.xml")) # 'codebook', 'lifecycle' ou 'cdi'
Plus de contrôle (avancé)¶
Si vous devez piloter vous-même les loaders, les classes de plus bas niveau restent disponibles :
import asyncio
from neo4j import AsyncGraphDatabase
from ddigraph import DDILoader, DDIFragmentLoader, detect_ddi_format
from ddigraph.config import Settings
from ddigraph.graph.bootstrap import ensure_schema
async def load_ddi(path: str, dataset_id: str = "default"):
settings = Settings()
driver = AsyncGraphDatabase.driver(
settings.neo4j_uri,
auth=(settings.neo4j_user, settings.neo4j_password.get_secret_value()),
)
try:
# Initialiser le schéma (sûr à exécuter à chaque fois)
await ensure_schema(driver, include_fragments=True)
# Choisir le bon chargeur selon le format
fmt = detect_ddi_format(path)
if fmt == "lifecycle":
loader = DDIFragmentLoader(driver, settings=settings)
result = await loader.load(path)
elif fmt == "cdi":
from ddigraph.ingest.cdi_loader import CDILoader
loader = CDILoader(driver, settings=settings)
result = await loader.load(path)
else:
loader = DDILoader(driver, settings=settings)
result = await loader.load(path, dataset_id=dataset_id)
return result
finally:
await driver.close()
result = asyncio.run(load_ddi("survey.xml", "my-survey"))
print(f"Chargé : {result}")
Étape 4 — Explorer vos données¶
Maintenant que vos données sont chargées, exécutez quelques requêtes pour voir ce qu'il y a.
Dans Neo4j Browser (http://localhost:7474)¶
-- Compter tous les nœuds par type
MATCH (n) RETURN labels(n) AS type, count(n) AS nombre ORDER BY nombre DESC
-- Lister toutes les variables d'un jeu de données
MATCH (d:Dataset {id: 'demo'})<-[:IN_DATASET]-(v:Variable)
RETURN v.name, v.label
-- Questions avec leurs listes de réponses
MATCH (q:QuestionItem)-[:USES_CODELIST]->(cl:CodeList)
RETURN q.name, q.question_text, cl.name
En Python (NetworkX)¶
import networkx as nx
# Trouver des chemins entre deux nœuds
paths = list(nx.all_simple_paths(G, source="instrument-1", target="question-5", cutoff=5))
# Exporter pour la visualisation
nx.write_graphml(G, "ddi_graph.graphml")
Et ensuite ?¶
- Vos premières requêtes — guide étape par étape pour explorer vos données
- Modèle relationnel — tous les types de nœuds et relations
- Optimisation des performances — optimiser pour les grands fichiers
- Référence CLI — toutes les commandes disponibles