摘要:后臺批量導入數據在生產環境中,往往數據不是幾條或者幾百條,那么舉個例子,將公司所有員工員工號或者帳號密碼導入進后臺,那就不建議你去后臺一條條記錄去添加了如何從中批量導入記錄第一步為數據建立模型修訂版本作者修訂時間注釋消息影響的文件創建時間修
django后臺批量導入數據
在生產環境中,往往數據不是幾條或者幾百條,那么舉個例子,將公司所有員工員工號或者帳號密碼導入進后臺,那就不建議你去后臺一條條記錄去添加了
如何從xml中批量導入svn記錄第一步:
為數據建立模型
@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"", )
既然建立好了模型,那我們再去建立接受我們xml文件的models
@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,以上代碼我們定義好了數據和上傳文件的model
同步數據庫
python manage.py makemigrations
python manage.py migrate
接著我們去修改admin.py 讓我們可以從后臺上傳文件,
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
注意上面代碼里的save_model,這里才是關鍵,在這里我重寫了ModelAdmin里的save_model方法
因為我們要把上傳文件,讀取文件,解析文件,操作數據庫合為一步來操作,大家可以打開debug,在上傳文件的時候,返回參數的obj里包括了文件上傳的路徑,這個路徑也是下一步我們操作解析文件的關鍵,好了我們在這個app文件夾下新建一個utils.py 用來操作我們操作文件和數據庫的工具類,為了簡單我寫成了函數如下
先貼一下我們要測試的xml文件
qwert 2016-09-27T07:16:37.396449Z /aaa/README 20160927 151630 VisualSVN Server 2016-09-20T05:03:12.861315Z /branches /tags /trunk hello word
輸出結果格式
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" ".join(pathlist) _paths = u"Changed paths: {}".format(_filelist) print _paths else: _filelist = paths.get("@action") + " " + paths.get("#text") _paths = u"Changed paths: {}".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)
我們使用的xmltodict這個第三方庫來解析xml,他把內容解析成了高效率的orderdict類型,就是有序列的字典
這個xml中比較復雜的是那個paths里的path,因為這個xml中包含兩個元素,第一個元素的path只含有一個path,第二個元素中的paths包含有三個path,因此我們在解析獲取的時候需要判斷一下
paths = j.get("paths").get("path") if isinstance(paths,list): pass
我們判斷這個path是不是一個list類型的,如果是,那我們就按照list的方式來處理,如果不是,那我們就按單個的方式來處理,獲取之后按照輸出結果格式處理下結果
然后獲取其他內容
revision = j.get("@vision") # get auth author = j.get("author") #get date date = j.get("date") #get msg msg = j.get("msg")
最后我們將獲取到的元素存在字典里
在循環中判斷當前的版本號和數據庫中的版本號,
如果比原來的小,那么我們執行更新操作,反之執行插入操作
最后使用了bulk_create來操作數據庫,這樣避免了循環中每次都進行數據庫操作造成的資源浪費
作者微信號:T_V_T_
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38196.html
摘要:總結整個過程的難點在于獲取文件對象,從數據中取值然后在按取出,這樣我們就可以從后臺上傳文件,然后進行批量導入數據庫,其他數據格式只需要改和中的數據字段就可以 第一篇(從django后臺解析excel數據批量導入數據庫) 文章會在github中持續更新 作者: knthony github 聯系我 1.django 如何從后臺上傳excel中批量解析數據 要從django后臺導入...
摘要:在這之前,還是有必要對一些概念超輕量級反爬蟲方案后端掘金前言爬蟲和反爬蟲日益成為每家公司的標配系統。 爬蟲修煉之道——從網頁中提取結構化數據并保存(以爬取糗百文本板塊所有糗事為例) - 后端 - 掘金歡迎大家關注我的專題:爬蟲修煉之道 上篇 爬蟲修煉之道——編寫一個爬取多頁面的網絡爬蟲主要講解了如何使用python編寫一個可以下載多頁面的爬蟲,如何將相對URL轉為絕對URL,如何限速,...
摘要:您的應用程序的目錄,它包含模式和回調函數之間的簡單映射。更性感自動生成的管理功能這個概述幾乎沒有觸及表面。 django概述 因為django是在快節奏的編輯環境下開發的,它旨在使常見的Web開發任務變得快速而簡單。 這是一個關于如何用django編寫數據庫驅動的Web應用程序的非正式概述。 本文檔的目的是為您提供足夠的技術細節來了解django的工作原理,但這不是一個教程或參考 - ...
摘要:跳槽時時刻刻都在發生,但是我建議大家跳槽之前,先想清楚為什么要跳槽。切不可跟風,看到同事一個個都走了,自己也盲目的開始面試起來期間也沒有準備充分,到底是因為技術原因影響自己的發展,偏移自己規劃的軌跡,還是錢給少了,不受重視。 跳槽時時刻刻都在發生,但是我建議大家跳槽之前,先想清楚為什么要跳槽。切不可跟風,看到同事一個個都走了,自己也盲目的開始面試起來(期間也沒有準備充分),到底是因為技...
摘要:激活虛擬環境,切換到文件所在的目錄下,分別運行和命令注意如果代碼中含有中文注釋,且你使用的是開發環境的話,會得到一個編碼錯誤。因此請在含有中文注釋的文件最開始處加入編碼聲明。在讓完成翻譯遷移數據庫追夢人物的博客的評論區留言。 我們已經編寫了博客數據庫模型的代碼,但那還只是 Python 代碼而已,Django 還沒有把它翻譯成數據庫語言,因此實際上這些數據庫表還沒有真正的在數據庫中創建...
閱讀 1698·2021-10-28 09:32
閱讀 605·2021-09-24 09:47
閱讀 2920·2021-09-02 15:11
閱讀 2733·2021-08-09 13:46
閱讀 2884·2019-08-30 15:55
閱讀 1071·2019-08-30 15:54
閱讀 3300·2019-08-29 14:12
閱讀 805·2019-08-26 13:40