1. 程式人生 > >在Django框架下向MongoDB資料庫中匯入.scv檔案資料

在Django框架下向MongoDB資料庫中匯入.scv檔案資料

在學習了一些MongoDB和Django框架的一些基礎知識後,我對MongoDB以及Django知識已經有了一個初步的掌握,是時候對學長的專案裡面的東西進行一個初步的實踐了,於是我選擇從Django框架中向MongoDB匯入資料的這部分程式碼開始。通過複用幾段學長專案裡的程式碼,在我自己新建的專案中實現向資料庫中匯入csv檔案。

1.新建一個Django專案

選擇Exisiting interpreter,開啟你的python安裝資料夾,選擇python.exe

建立好後會得到如下介面

其中,與專案同名的vis1目錄是專案的核心檔案;templates目錄是HTML檔案存放處,也就是MTV中的T。manage.py是Django專案管理檔案。

在核心檔案vis1目錄中:

_init_.py:空檔案

settings.py:主配置檔案

urls.py:主路由檔案

wsgi.py:閘道器介面

2.建立APP

在每個Django專案中可以包含多個APP,相當於一個大型專案中的分系統、子模組、功能部件等等,相互之間比較獨立,但也可以有聯絡。所有的APP共享專案資源。要在Django框架下連結MongoDB,我們就必須建立一個APP。(為了方便我複用學長專案中的程式碼,我建立了一個與學長相同的APP:datas)

在Pycharm下方的Terminal終端中輸入命令:

python manage.py startapp datas

建立好後,django自動生成“datas”資料夾,及一系列檔案: (注意:如果你選擇vis1->new->python package這樣的方式得到的資料夾裡將沒有這一系列的檔案)

3.編輯APP

 在Datas中,models是與資料庫操作相關,存入或讀取資料的檔案,所以首先我們需要對它進行配置。剛開啟裡面只有一句引入庫的語句,你需要在這裡編寫對你要匯入資料庫的列名進行定義:

 因為是為了理解並實踐學長的程式碼,我這裡就直接貼上學長專案中的這部分程式碼了:

from django.db import models
from mongoengine import *
# Create your models here.

class Alldata(models.Model):
    id = models.BigIntegerField(primary_key=True)
    ipsmalltype = models.IntegerField()
    filelen = models.BigIntegerField()
    fileaffix = models.CharField(max_length=10, null=True)
    iscracked = models.NullBooleanField()
    starttime = models.DateTimeField()
    srcip = models.CharField(max_length=45)
    dstip = models.CharField(max_length=45)
    srcport = models.IntegerField()
    dstport = models.IntegerField()
    vpi1 = models.IntegerField(null=True)
    vpi2 = models.IntegerField(null=True)
    atm1aaltype = models.IntegerField(null=True)

4.註冊APP

 在配置好了models之後,你要讓你的資料庫知道該給那個APP建立表,所以需要在vis1目錄的settings中註冊APP。也就是在

settings中的INSTALLED_APPS中新增你剛才建立好的datas

5.連線mongoDB

一般在Django框架中連線資料庫都需要對settings中的DATABASES進行配置,如下圖:

而我們這裡使用MongoDB資料庫,它可以不使用DATABASES,在學長的程式碼中,他是這樣做的:

在DATABASES旁邊建立一個DBCONFIG,然後將DATABSES中的內容刪掉:

這樣,每次連線MongoDB時只需要呼叫DBCONFIG就行了

6.編寫匯入csv部分的程式碼

先建立一個.py檔案,然後在裡面編寫向資料庫中匯入資料功能的程式碼,我這裡就直接複製學長的專案中有關這一段的程式碼:


class Data2Mongo:
    filename = 'ip{}.csv-資料處理.csv'
    path = 'C:\\Users\\Administrator\\Desktop\\ChinaVis\\2016年資料可視分析挑戰賽-挑戰1-資料\\'
    count = range(1, 11)
    c_raw = 'raw_data'
    c_clear = 'clear_data'
    c_uncracked = 'uncracked_data'
    c_merge = 'merge_data'
    colname = ['ipsmalltype', 'filelen', 'fileaffix', 'iscracked', 'starttime',
               'srcip', 'dstip', 'srcport', 'dstport', ' vpi1', 'vpi2', 'atm1aaltype']
    checklist = ['ipsmalltype', 'filelen', 'fileaffix', 'iscracked', 'starttime',
                 'srcip', 'dstip', 'srcport', 'dstport', 'vpi1', 'vpi2', 'atm1aaltype']
    checklist_merge = ['ipsmalltype', 'fileaffix', 'starttime', 'srcip',
                       'dstip', 'srcport', 'dstport', 'vpi1', 'vpi2', 'atm1aaltype']
    res = []
    max_len = 100000

    def __init__(self):
        self.files = []
        for i in self.count:
            self.files.append(self.filename.format(i))
        self.client = MongoClient(DBCONFIG['HOST'], DBCONFIG['PORT'])
        self.db = self.client.__getattr__(DBCONFIG['NAME'])
        self.dst_raw = self.db[self.c_raw]
        self.dst_clear = self.db[self.c_clear]
        self.dst_uncracked = self.db[self.c_uncracked]
        self.dst_merge = self.db[self.c_merge]

    def __del__(self):
        self.client.close()

    @staticmethod
    def convert_fileaffix(fileaffix):
        if len(fileaffix) == 0:
            return ''
        while fileaffix[0] == '.':
            fileaffix = fileaffix[1:]
        if '.' in fileaffix:
            return None
        else:
            return fileaffix

    def data2mongo(self):
        self.dst_raw.remove({})
        self.res.clear()
        for i in self.count:
            print('正在處理檔案:%s' % (self.path + self.filename.format(i)))
            with open(self.path + self.filename.format(i)) as infile:
                reader = csv.reader(infile)
                next(reader)
                for row in reader:
                    fileaffix = self.convert_fileaffix(str(row[3]))
                    if fileaffix is None:
                        continue
                    self.res.append({
                        'ipsmalltype': int(row[1]),
                        'filelen': int(row[2]),
                        'fileaffix': fileaffix if fileaffix != '' else None,
                        'iscracked': int(row[4]) if row[4] == '0' else 1,
                        'starttime': datetime.strptime(row[5], '%Y/%m/%d %H:%M:%S'),
                        'srcip': str(row[6]),
                        'dstip': str(row[7]),
                        'srcport': int(row[8]),
                        'dstport': int(row[9]),
                        'vpi1': int(row[10]) if row[10] != '' else None,
                        'vpi2': int(row[11]) if row[11] != '' else None,
                        'atm1aaltype': int(row[12]) if row[12] != '' else None
                    })
                    if self.res.__len__() == self.max_len:
                        self.dst_raw.insert_many(self.res)
                        self.res.clear()
        if self.res.__len__() > 0:
            self.dst_raw.insert_many(self.res)
            self.res.clear()

記得把需要匯入的庫及要引用的檔案匯入,不然會報錯:

from pymongo import MongoClient
from datetime import datetime
from vis.settings import DBCONFIG
import csv

其次,需要注意匯入的檔案路徑一定要正確,檔名之間的分隔符是\\,別寫反了

7.編寫一個呼叫Data2Mongo的.py檔案

我這裡建立一個handles.py(為避免複用學長的程式碼出錯,所以取了和學長專案中一樣的名稱)

from data2mongo import Data2Mongo

import time
if __name__ == '__main__':
    start = time.clock()
    tomongo = Data2Mongo()
    tomongo.data2mongo()

 8.執行handles.py

 

這樣,在Django框架下向MongoDB匯入.csv檔案便實現了。

用Navicate for MongoDB我們可以檢視到我們匯入的資料如圖: