Je travaille dans une entreprise qui possède une grande base de données et je souhaite effectuer quelques requêtes de mise à jour dessus mais cela semble provoquer une énorme fuite de mémoire la requête est la suivante
with transaction.atomic()
J'ai écrit ceci dans le shell interactif de Django
J'ai même essayé d'utiliser
c= CallLog.objects.all() for i in c: i.cdate = pytz.utc.localize(datetime.datetime.strptime(i.fixed_date, "%y-%m-%d %H:%M")) i.save()
mais cela n'a pas fonctionné, avez-vous une idée de comment puis-je détecter la source de
l'ensemble de données sur lequel je travaille est d'environ 27 millions
fixed_date est une propriété calculée
3 Réponses :
Vous pouvez essayer quelque chose comme ceci:
from django.core.paginator import Paginator p = Paginator(CallLog.objects.all().only('cdate'), 2000) for page in range(1, p.num_pages + 1): for i in p.page(page).object_list: i.cdate = pytz.utc.localize(datetime.datetime.strptime(i.fixed_date, "%y-%m-%d %H:%M")) i.save()
Le découpage d'un ensemble de requêtes ne charge pas tous les objets en mémoire uniquement pour obtenir un sous-ensemble mais ajoute une limite et un décalage à la requête SQL avant de frapper le base de données.
Je pense que ce morceau de code met à jour toute la table avec la même valeur, et je veux mettre à jour chaque enregistrement avec sa valeur de fixed_date calculée. J'ai pensé à l'expression F () mais cela ne fonctionne pas avec les propriétés calculées
@AhmedIbrahim J'ai édité ma réponse. Essayez ceci, cela devrait fonctionner un peu mieux. Si cela prend du temps et consomme de la mémoire, vous devez penser à créer une tâche asynchrone et informer l'utilisateur quand c'est terminé.
J'essaierai celui-ci et je vous répondrai
cela fonctionne parfaitement mais si lentement, mais cela n'a pas d'importance car je ne le fais qu'une fois
Vous pouvez essayer d'itérer l'ensemble de requêtes par lots; voir Voici un réponse J'ai trouvé, mais il a quelques années. .iterator ()
une méthode>. Voyez si cela améliore quelque chose for obj in CallLog.objects.all():
obj.cdate = pytz.utc.localize(
datetime.datetime.strptime(obj.fixed_date, "%y-%m-%d %H:%M"))
obj.save()
Essayez de le diviser en petits blocs (puisque vous n'avez que 4 Go de RAM)
c= CallLog.objects.filter(somefield=somevalue)
Lorsque c'est nécessaire, j'utilise généralement un caractère ou un nombre (ID entrant en 1,2,3, 4 etc)
Pourquoi dites-vous que c'est une fuite de mémoire? Que se passe-t-il lorsque vous exécutez ce code? Une trace de pile d'erreur que vous pourriez ajouter?
J'ai une machine mémoire de 4 Go et quand je lance htop, je vois que toute la mémoire a été mangée par Django et le système se fige après cela
Vous devez utiliser Redis ou une sorte de gestionnaire de file d'attente pour traiter toutes les données 1 par 1