0

Dans le cadre d'un projet sur lequel je travaille, j'essaie de construire une structure de données hiérarchique d'objets de différents types.Django ORM - Construire une structure hiérarchique de données avec plusieurs modèles

J'ai utilisé django-mptt pour cela, qui promet de gérer les arbres de manière intelligente avec des requêtes rapides. Le problème est, que j'ai plusieurs modèles qui doivent participer à cet arbre de données, j'ai donc utilisé une relation générique afin de stocker les données requises.

Un extrait du modèle I construit:

class CPNode(MPTTModel): 
    content_type = models.ForeignKey(ContentType, null=True, blank=True) 
    object_id = models.PositiveIntegerField(null=True) 
    content_object = GenericForeignKey('content_type', 'object_id') 
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True) 
... 

Cela me donne ce que je veux, à l'exception de la question de la requête. Je suppose que demander toutes les données coûtera plusieurs requêtes (chaque fois que je voudrais obtenir l'objet content_object lui-même).

Quelqu'un at-il une idée de comment je peux maintenir cette structure, et en même temps être en mesure d'obtenir toutes les données dans une requête évolutive?

+0

Quel est le problème exact que vous rencontrez? Vous avez choisi d'utiliser la base de données relationnelle pour cela, donc vous ne pouvez pas éviter d'avoir des JOINs dans ces types de requêtes. Utilisez ['prefetch_related'] (https://docs.djangoproject.com/fr/1.11/ref/models/querysets/#django.db.models.query.QuerySet.prefetch_related) si vous avez besoin de récupérer directement' content_object' dans vos requêtes, pour éviter plusieurs requêtes. Que ce soit évolutif dépend de vos données. Une base de données NoSQL pourrait être mieux adaptée à ce type d'arbre. – dirkgroten

+0

Le problème est que cette grande partie de ces données est déjà en production. donc passer à NoSQL DB est mon dernier recours. Je n'ai pas encore commencé, mais en pensant à l'avance, il semble que l'interrogation d'un grand arbre avec plusieurs types de nœuds sera un gâchis. J'ai plusieurs types d'actifs dont chaque type est géré par un modèle, et chaque actif peut avoir un actif inférieur aux types de variables. –

Répondre

0

Les bases de données relationnelles (au moins les bases de données SQL) ne sont pas géniales pour les arborescences hétérogènes ... MPTT améliorera grandement la lecture des fichiers perfs en évitant les requêtes récursives, mais cela ne résoudra pas le problème GenericForeignKey - il n'y a tout simplement aucun moyen d'implémenter une telle fonctionnalité au niveau SQL, donc si vous l'utilisez, oui, vous aurez besoin d'une requête de plus par nœud pour obtenir le contenu efficace. La seule façon d'éviter ces requêtes supplémentaires serait d'entasser chaque champ de chaque sous-type de nœud dans le même modèle, d'y ajouter un champ "node_type" et d'utiliser des modèles de proxy par nœud. Le code ne sera pas joli (été ici, fait ça) mais bon, il y a peu d'autres options ici ...