Heim >Backend-Entwicklung >Python-Tutorial >Django Batch importiert XML-Daten
Django Hintergrund-Batch-Importdaten
In einer Produktionsumgebung gibt es oft nicht wenige oder Hunderte von Daten, also zum Beispiel die Mitarbeiternummer oder das Konto und Passwörter werden in das Backend importiert, daher wird nicht empfohlen, dass Sie zum Backend gehen, um Datensätze einzeln hinzuzufügen
So importieren Sie SVN-Datensätze stapelweise aus XML
Schritt eins:
Erstellen Sie ein Modell für die Daten
@python_2_unicode_compatible class SVNLog(models.Model): vision = models.IntegerField(verbose_name=u"修订版本", blank=False, null=False,) author = models.CharField(verbose_name=u"作者", max_length=60, blank=True, null=True) date = models.DateTimeField(verbose_name=u"修订时间",null=True ) msg = models.TextField(verbose_name=u"注释消息", blank=False, null=False, default=u"") paths = models.TextField(verbose_name=u"影响的文件", blank=False, null=False, default=u"") created_time = models.DateTimeField(verbose_name=u"创建时间", auto_now_add=True, ) update_time = models.DateTimeField(verbose_name=u"修改时间", auto_now=True, ) class Meta: ordering = ['revision'] def __str__(self): return u'r%s' % (self.revision or u"", )
Nachdem das Modell erstellt wurde, Erstellen wir es so, dass es unsere XML-Dateimodelle akzeptiert
@python_2_unicode_compatible class ImportLogFile(models.Model): LogFile = models.FileField(upload_to='LogFile') FileName = models.CharField(max_length=50, verbose_name=u'文件名') class Meta: ordering = ['FileName'] def __str__(self): return self.FileName
OK, im obigen Code haben wir die Daten definiert und Dateimodelle hochgeladen
Synchronisieren Sie die Datenbank
python manage.py makemigrations python manage.py migrate
Dann ändern wir admin.py, damit wir Dateien von hochladen können der Hintergrund,
class ImportLogAdmin(admin.ModelAdmin): list_display = ('LogFile','FileName',) list_filter = ['FileName',] def save_model(self, request, obj, form, change): re = super(YDImportLogAdmin,self).save_model(request, obj, form, change) update_svn_log(self, request, obj, change) return re
Achten Sie auf save_model im obigen Code. Dies ist der Schlüssel. Hier schreibe ich die save_model-Methode in ModelAdmin um Wir müssen Dateien hochladen und in einem Schritt lesen, die Datei analysieren und die Datenbank betreiben. Beim Hochladen der Datei enthält der Rückgabeparameter obj auch den Pfad Schlüssel zu unserem nächsten Schritt des Parsens der Datei. Okay, wir erstellen eine neue utils.py in diesem App-Ordner, um die Tool-Klasse zu betreiben, die wir zum Betreiben von Dateien und Datenbanken verwenden. Der Einfachheit halber habe ich die Funktion wie folgt geschrieben:
Zuerst einfügen die XML-Datei, die wir testen möchten
qwert2016-09-27T07:16:37.396449Z/aaa/README20160927 151630VisualSVN Server2016-09-20T05:03:12.861315Z/branches/tags/trunkhello wordAusgabeergebnisformat
r2 | qwer | 2016-09-27 15:16:37 +0800 (二, 27 9 2016) | 1 line Changed paths: A /xxx/README 20160927 151630 ------------------------------------------------------------------------ r1 | VisualSVN Server | 2016-09-20 13:03:12 +0800 (二, 20 9 2016) | 1 line Changed paths: A /branches A /tags A /trunk Initial structure. from .models import SVNLog import xmltodict def update_svn_log(self, request, obj, change): headers = ['r','a','d','m','p'] filepath = obj.LogFile.path xmlfile = xmltodict.parse(open(filepath, 'r')) xml_logentry = xml.get('log').get('logentry') info_list = [] pathlist = [] sql_insert_list = [] sql_update_list = [] for j in xml: data_dict = {} # get path paths = j.get('paths').get('path') if isinstance(paths,list): for path in paths: action = path.get('@action') pathtext = path.get('#text') pathtext = action + ' ' + pathtext pathlist.append(pathtext) _filelist = u'\n'.join(pathlist) _paths = u"Changed paths:\n {}".format(_filelist) print _paths else: _filelist = paths.get('@action') + ' ' + paths.get('#text') _paths = u"Changed paths:\n {}".format(_filelist) print _paths # get revision vision = j.get('@vision') # get auth author = j.get('author') #get date date = j.get('date') #get msg msg = j.get('msg') data_dict[headers[0]] = int(vision) data_dict[headers[1]] = author data_dict[headers[2]] = date data_dict[headers[3]] = msg data_dict[headers[4]] = _paths info_list.append(data_dict) _svnlog = SVNLog.objects.filter().order_by('-vision').first() _last_version = _svnlog.vision if _svnlog else 0 for value in info_list: vision = value['r'] author = value['a'] date = value['d'] msg = value['m'] paths = value['p'] print vision,author _svnlog = YDSVNLog.objects.filter().order_by('-revision').first() _last_version = _svnlog.revision if _svnlog else 0 if vision > _last_version: sql_insert_list.append(SVNLog(revision=revision, author=author, date=date, msg = msg, paths = paths)) else: sql_update_list.append(SVNLog(revision=revision, author=author, date=date, msg = msg, paths = paths)) SVNLog.objects.bulk_create(sql_insert_list) SVNLog.objects.bulk_create(sql_update_list)Die Drittanbieter-Bibliothek xmltodict, die wir zum Parsen von XML verwenden. Er analysiert den Inhalt in einen effizienten Orderdict-Typ, der ein sequenziertes Wörterbuch ist.
Das Kompliziertere in dieser XML ist der Pfad in Pfaden, da diese XML zwei enthält Elemente, und der Pfad des ersten Elements enthält nur einen Pfad. Die Pfade im zweiten Element enthalten drei Pfade, daher müssen wir beim Parsen und Erhalten
paths = j.get('paths').get('path') if isinstance(paths,list): pass
Wir beurteilen diesen Pfad. Handelt es sich um einen Listentyp? Wenn nicht, verarbeiten wir ihn auf eine einzige Weise. Nachdem wir ihn erhalten haben, verarbeiten wir ihn entsprechend in das Ausgabeergebnisformat konvertieren und dann andere Inhalte abrufen
revision = j.get('@vision') # get auth author = j.get('author') #get date date = j.get('date') #get msg msg = j.get('msg')
Schließlich werden wir die erhaltenen Elemente im Wörterbuch speichern
Beurteilen Sie die aktuelle Versionsnummer und die Versionsnummer in der Datenbank in der Schleife,Wenn sie verglichen wird Das Original ist klein, dann führen wir den Aktualisierungsvorgang durch und umgekehrt
Schließlich wird bulk_create zum Betreiben der Datenbank verwendet, was vermeidet die Verschwendung von Ressourcen, die jedes Mal in der Schleife durch Datenbankoperationen verursacht wird