2013-06-07 1 views
2

Je peux voir plusieurs options différentes pour ce faire et j'aimerais obtenir des commentaires sur la méthode la plus efficace ou la «meilleure pratique».La manière la plus efficace d'obtenir la liste des valeurs de Django Queryset

je reçois un Django QuerySet avec filtre()

c_layer_points = models.layer_points.objects.filter(location_id=c_location.pk,season_id=c_season.pk,line_path_id=c_line_path.pk,radar_id=c_radar.pk,layer_id__in=c_layer_pks,gps_time__gte=start_gps,gps_time__lte=stop_gps) 

Ce queryset pourrait être très grande (des centaines de milliers de lignes).

Maintenant, ce qui doit arriver est une conversion en listes et un encodage en JSON.

Options (que je l'ai vu dans mes recherches):

  1. Boucle sur le queryset

Exemple:

gps_time = [lp.gps_time for lp in c_layer_points]; 
twtt = [lp.twtt for lp in c_layer_points]; 
  1. Les valeurs d'usage() ou values_list (
  2. Utiliser l'itérateur()

En fin de compte, je voudrais encoder comme JSON quelque chose comme ce format:

{'gps_time':[list of all gps times],'twtt',[list of all twtt]} 

Les conseils sur la meilleure façon de le faire serait génial, Merci!

+0

Pourquoi ne pas vous venez de faire les mesures vous-même? 'importer datetime; start = datetime.time(); end = datetime.time(); print (end-start) ' – J0HN

+0

J'ai et je continuerai à le faire. Cependant, je voulais avoir une idée de ce que les «meilleures pratiques» seraient ici. D'autant plus que quelques options sont presque les mêmes du point de vue de l'efficacité. –

Répondre

4

Vous ne pourrez peut-être pas obtenir le format requis auprès de l'ORM. Cependant, vous pouvez efficacement faire quelque chose comme ceci:

c_layer_points = models.layer_points.objects.filter(location_id=c_location.pk, season_id=c_season.pk, line_path_id=c_line_path.pk,radar_id=c_radar.pk, layer_id__in=c_layer_pks, gps_time__gte=start_gps, gps_time__lte=stop_gps).values_list('gps_time', 'twtt') 

et maintenant diviser les tuples en deux listes: (Tuple déballer)

split_lst = zip(*c_layer_points)  
dict(gps_time=list(split_lst[0]), twtt=list(split_lst[1])) 
+1

Notez que même avec '.values_list()' (ou '.iterator()' ou quoi que ce soit d'autre, je peux dire), django va lire tous les enregistrements en mémoire. Idéal pour les performances SQL, pas si bon pour la mémoire si nous parlons de grandes lignes. Mon processus python utilisé> 300 Mo de RAM. J'ai fini par utiliser 'Paginator' pour faire défiler des morceaux d'enregistrements. La mémoire contre la vitesse est un compromis, et je me suis installé sur 10.000 dossiers à la fois. –

3

Je vous suggérerais d'utiliser l'itération dans l'ensemble de requêtes et de conformer l'élément dictionnaire json par élément à partir du jeu de requête.

Normalement, les QuerySets de Django sont paresseux, ce qui signifie qu'ils sont chargés en mémoire à chaque accès. Si vous chargez la liste entière: gps_time = [lp.gps_time for lp in c_layer_points] vous aurez tous ces objets en mémoire (milliers). Vous serez bien en faisant une itération simple:

for item in c_layer_points: 
    #convert item to json and add it to the 
    #json dict. 

En aparté note, vous n'avez pas besoin le caractère ; à la fin des lignes en python :)

Hope this helps!

+0

Super, je vais jeter un oeil à cela. Aussi je sais sur le ";" MATLAB est ma langue principale (ceci change!) Ainsi c'est juste une habitude sale! –

+0

Hehehe été là, j'ai programmé en C++, C# avant;) –

+0

Je ne suis pas sûr que cela fonctionnera pour moi. J'ai en fait besoin de faire quelques opérations sur les données (ce qui signifie que je dois vraiment les charger dans la mémoire sous forme de listes).Par exemple, je dois faire une interpolation basée sur les éléments de c_layer_points. –

Questions connexes