Ich habe einen Code geschrieben, der die Auswahl in eine Tabelle ausgibt, in der eine große Anzahl von Datensätzen gespeichert ist, das Ergebnis an csv ausgibt und es komprimiert. Machen Sie sich also eine Notiz.
models.py
from logging import getLogger
from django.db import models
import uuid
logger = getLogger(__name__)
class Analytics(models.Model):
hit_type = models.CharField(max_length=20)
category = models.CharField(max_length=255, null=True, blank=True)
action = models.CharField(max_length=255, null=True)
label = models.CharField(max_length=255, null=True, blank=True)
value = models.IntegerField(null=True)
url = models.CharField(max_length=255, null=True)
created = models.DateTimeField(auto_now_add=True, db_index=True)
tracking_user = models.ForeignKey('app.TrackingUser', related_name='analytics')
def __str__(self):
return '%s - %s' % (self.category, self.tracking_user.uuid)
class TrackingUser(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return str(self.uuid)
Es gab ein Modell, das Daten speichert, die das Benutzerverhalten auf der Website wie oben beschrieben verfolgen. Dieses Mal wollte ich jedoch einen Befehl erstellen, der gelöscht werden kann, nachdem Analytics-Datensätze einen Monat lang erfasst und in CSV gespeichert wurden. .. Übrigens steigen die Analytics-Daten an einem Tag um etwa 100.000, also um etwa 3 Millionen pro Monat. Aufgrund der verschiedenen Aktionen war der folgende Code ein gutes Gefühl.
delete_analytics.py
from datetime import datetime, timedelta, date
from api.models import Analytics
from pytz import timezone, utc
from django.core.management.base import BaseCommand
from django.db import transaction
from dateutil.relativedelta import relativedelta
import csv
import gzip
import shutil
import os
class Command(BaseCommand):
def add_arguments(self, parser):
# Named (optional) arguments
parser.add_argument('--target_date', metavar='target_date', type=str, nargs=None,
help='target date')
@transaction.atomic
def handle(self, *args, **options):
if options['target_date']:
delete_start_date = datetime.strptime(options['target_date'], '%Y-%m-%d').replace(day=1)
else:
this_month = date.today().replace(day=1)
delete_start_date = this_month - relativedelta(months=3)
delete_end_date = delete_start_date + relativedelta(months=1)
queryset = Analytics.objects.select_related('user', 'tracking_user').filter(created__range=(delete_start_date, delete_end_date))
#Ausgabe an csv
filename_date = delete_start_date.strftime('%Y%m')
filename = filename_date + "_event.csv"
model = queryset.model
writer = csv.writer(open(filename, 'w'))
##Schreiben des Header-Teils von csv
headers = []
for field in model._meta.fields:
headers.append(field.name)
writer.writerow(headers)
##Schreiben Sie den abgerufenen Datensatz
for obj in queryset:
row = []
for field in headers:
val = getattr(obj, field)
if callable(val):
val = val()
row.append(val)
writer.writerow(row)
#Komprimiere csv mit gzip
with open(filename, 'rb') as gzip_in:
with gzip.open(filename + ".gz", 'wb') as gzip_out:
shutil.copyfileobj(gzip_in, gzip_out)
os.remove(filename)
queryset.delete()
Wenn Sie in dem Verzeichnis, in dem sich manage.py befindet, "./manage.py delete_analytics.py -target_date = 2017-06-01" festlegen, werden die Daten für Juni 2017 in 201706_event.csv ausgegeben, mit gzip weiter komprimiert und dann , Gelöscht.
Die folgenden Teile waren diesmal der Schlüssel.
python
queryset = Analytics.objects.select_related( 'tracking_user').filter(created__range=(delete_start_date, delete_end_date))
Wenn Sie nicht "select_related" ("tracking_user") schreiben, wird auch das Beziehungsziel ausgewählt, sodass dies einige Zeit in Anspruch nimmt. Als ich es schrieb, endete der Befehl in 5 Minuten, aber wenn ich ihn nicht schrieb, dauerte es 50 Minuten, bis er fertig war.
Als ich es auf dem Server ausführte, fiel es aufgrund von Speichermangel ... Überlegen Sie, was zu tun ist, und schreiben Sie erneut, wenn Sie damit umgehen können
django recipe: dump your queryset out as a csv file . palewire
Recommended Posts