首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Django 後台批量導入 SVN 日誌數據完整實戰指南

     編輯:Java 相關知識

項目背景

生產環境中常需批量導入大量歷史數據(如員工賬號、SVN 提交記錄等)。手動逐條錄入效率極低,本文介紹基於 Django Admin 的 XML 文件批量導入方案,實現文件上傳、解析、入庫一體化流程。

數據模型設計

SVN 日誌模型

@python_2_unicode_compatible
class SVNLog(models.Model):
    revision = models.IntegerField(verbose_name="修訂版本", blank=False, null=False)
    author = models.CharField(verbose_name="作者", max_length=60, blank=True, null=True)
    date = models.DateTimeField(verbose_name="修訂時間", null=True)
    msg = models.TextField(verbose_name="正文信息", blank=False, null=False, default="")
    paths = models.TextField(verbose_name="影響的文件", blank=False, null=False, default="")
    created_time = models.DateTimeField(verbose_name="創建時間", auto_now_add=True)
    update_time = models.DateTimeField(verbose_name="修改時間", auto_now=True)

    class Meta:
        ordering = ['revision']

    def __str__(self):
        return 'r%s' % (self.revision or "")

導入文件記錄模型

@python_2_unicode_compatible
class ImportLogFile(models.Model):
    log_file = models.FileField(upload_to='LogFile')
    file_name = models.CharField(max_length=50, verbose_name='文件名')

    class Meta:
        ordering = ['file_name']

    def __str__(self):
        return self.file_name

數據庫遷移

python manage.py makemigrations
python manage.py migrate

Admin 後台集成

class ImportLogAdmin(admin.ModelAdmin):
    list_display = ('log_file', 'file_name')
    list_filter = ['file_name']

    def save_model(self, request, obj, form, change):
        # 先保存文件記錄
        re = super(ImportLogAdmin, self).save_model(request, obj, form, change)
        # 解析並入庫
        update_svn_log(self, request, obj, change)
        return re

關鍵點:重寫 save_model 方法,在文件保存後自動觸發解析邏輯,obj.log_file.path 可獲取上傳文件的服務器路徑。

XML 文件結構示例

<?xml version="1.0" encoding="UTF-8"?>
<log>
  <logentry revision="2">
    <author>qwert</author>
    <date>2016-09-27T07:16:37.396449Z</date>
    <paths>
      <path action="A" prop-mods="false" text-mods="true" kind="file">/aaa/README</path>
    </paths>
    <msg>20160927 151630</msg>
  </logentry>
  <logentry revision="1">
    <author>VisualSVN Server</author>
    <date>2016-09-20T05:03:12.861315Z</date>
    <paths>
      <path action="A" prop-mods="false" text-mods="false" kind="dir">/branches</path>
      <path action="A" prop-mods="false" text-mods="false" kind="dir">/tags</path>
      <path action="A" prop-mods="false" text-mods="false" kind="dir">/trunk</path>
    </paths>
    <msg>hello word</msg>
  </logentry>
</log>

核心解析邏輯 (utils.py)

from .models import SVNLog
import xmltodict

def update_svn_log(self, request, obj, change):
    filepath = obj.log_file.path
    xmlfile = xmltodict.parse(open(filepath, 'r'))
    xml_logentry = xmlfile.get('log').get('logentry')
    
    # 兼容單個/多個 path 元素
    for entry in xml_logentry:
        paths = entry.get('paths', {}).get('path', [])
        if not isinstance(paths, list):
            paths = [paths]
        
        path_list = []
        for path in paths:
            action = path.get('@action', '')
            path_text = path.get('#text', '')
            path_list.append(f"{action} {path_text}")
        
        paths_str = "Changed paths:\n " + "\n ".join(path_list)
        
        revision = int(entry.get('@revision', 0))
        author = entry.get('author', '')
        date_str = entry.get('date', '')
        msg = entry.get('msg', '')
        
        # 判斷是新增還是更新
        last_revision = SVNLog.objects.order_by('-revision').first()
        last_version = last_revision.revision if last_revision else 0
        
        if revision > last_version:
            SVNLog.objects.create(
                revision=revision,
                author=author,
                date=date_str,
                msg=msg,
                paths=paths_str
            )
        else:
            SVNLog.objects.filter(revision=revision).update(
                author=author,
                date=date_str,
                msg=msg,
                paths=paths_str
            )

關鍵技術點解析

  1. xmltodict 庫:將 XML 轉為有序字典,簡化解析邏輯
  2. 動態類型處理:isinstance(paths, list) 兼容單個/多個 path 元素
  3. 批量操作優化:實際項目中建議收集對象列表後使用 bulk_create/bulk_update 減少數據庫交互
  4. 增量導入邏輯:對比版本號決定插入或更新,避免重複數據

擴展建議

  • 添加導入進度顯示(大文件解析耗時長)
  • 實現異步任務隊列(Celery)避免阻塞請求
  • 增加數據校驗與錯誤回滾機制
  • 支持多種日誌格式(JSON、CSV 等)
  • 添加導入歷史記錄與回滾功能

總結

通過 Django Admin 重寫 save_model 結合 xmltodict 解析庫,實現了 SVN 日誌 XML 文件的批量自動化導入。此模式可推廣到各類結構化文件的後台導入場景,關鍵在於模型設計、解析邏輯封裝與批量操作優化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved