Django: Как импортировать данные из CSV в базу данных без использования формы? - PullRequest
0 голосов
/ 09 ноября 2018

Я очень новичок в Django, на самом деле очень плохо знаком с кодированием. Я знаю, что это глупый вопрос, но я понятия не имею, как это сделать.

Я хотел импортировать некоторые данные из локального CSV-файла и сохранить их в базе данных (у меня есть mysql) без создания формы загрузки (почти из учебников, которые я нашел в Google).

Я очень запутался в модели MVC, например. где часть обработки csv должна стоять? вид или модель? а также я должен создать функцию, чтобы вырезать нежелательные поля из CSV. куда я должен поместить этот код?

Вот моя модель

from __future__ import unicode_literals
import csv, io
from django.conf import settings
from django.db import models

#from django_countries.fields import CountryField

class ASN(models.Model):
    num = models.IntegerField(primary_key=True)
    owner = models.CharField(max_length=50, null=True)
    # Using countryfield to convert from country code to name
    countryCode = models.CharField(max_length=5)
    name = models.CharField(max_length=100, null=True)
    #countryName = CountryField()

    def __str__(self):
        return str(self.owner) + " " + str(self.num) + " " + str(self.countryCode)

class Host(models.Model):
    name = models.CharField(max_length=20)
    id = models.IntegerField(primary_key=True)

    def __str__(self):
        return str(self.id) + " " + str(self.name)

class Peer(models.Model):
    router_ip = models.CharField(max_length=20, primary_key=True)
    bgp_state = models.IntegerField(default=0) 
    as_num = models.ForeignKey('ASN', on_delete=models.CASCADE)
    host_id = models.ForeignKey('Host', on_delete=models.CASCADE)

    def __str__(self):
        return str(self.host_id) + ' ' + str(self.router_ip) + ' ' + str(self.as_num) + ' ' + str(self.bgp_state)

class PeerNeighbor(models.Model):
    neighbor_ip = models.CharField(max_length=20, primary_key=True)
    router_ip = models.ForeignKey('Peer', on_delete=models.CASCADE)

    def __str__(self):
        return str(self.router_ip) + ' ' + str(self.neighbor_ip)

Вот код для удаления ненужных полей (автономный файл)

import csv

txt_file_id = r'MR-SG1-BGPPEER.txt'
txt_file_AS = r'show_AS.txt'
csv_file_out = r'file_out.csv'
peer = []
bgp_peer = []
remote_router_id = []
AS_number = []
AS = []
router_ip = []

def main():
    readInput(txt_file_id, txt_file_AS)
    writeOutput(csv_file_out)

def readInput(filename_1, filename_2):
    with open(filename_1, newline='') as csvfile_1:
        spamreader1 = csv.reader(csvfile_1, delimiter=' ', quotechar=" ")
        for row in spamreader1:
            row = ','.join(row)
            row = row.split(',')
            bgp_peer = row[0]
            remote_router_id = row[3]
            bgp_peer = split_list(bgp_peer)
            peer.append(bgp_peer) #store results into list
            router_ip.append(remote_router_id)
        #print(peer)

    with open(filename_2, newline='') as csvfile_2:
        spamreader2 = csv.reader(csvfile_2, delimiter=' ', quotechar=" ")
        for row in spamreader2:
            row = ','.join(row)
            row = row.split(',')
            AS_number = row[3]
            AS.append(AS_number) #store results into list
        #print(AS)
    print(peer, AS)

def writeOutput(filename):
    with open(filename, 'w') as outputFile:
        wr = csv.writer(outputFile, quoting=csv.QUOTE_ALL)
        wr.writerow(zip(router_ip, peer, AS))

def split_list(inputlist):
    string = inputlist.split(".")
    count = 0
    for i in string:
        count+=1
    bgp_peer_ip = string[5:count]
    bgp_peer_ip = '.'.join(bgp_peer_ip)
    return(bgp_peer_ip)   
main()

второй файл выдаст router_ip, neighbour_ip и asn. Нужно ли создавать новый класс в модели, чтобы сохранить данные? Могу ли я добавить данные в определенный класс вместо создания нового, например, сохранить router_ip для класса Peer, соседний_ip для класса PeerNeighbor и сохранить asn для класса ASN.

это новый класс для хранения данных из csv (внутри модели), но он не работал.

class dataFromFile(models.Model):
    router_ip = models.CharField(max_length=20, primary_key = True)
    as_num = models.IntegerField(default=0)
    neighbor_ip = models.CharField(max_length=20)
    objects = models.Manager()

def import_db(request):
    f = open('/home/Jobs/Peering_db/file_out.csv')
    for line in f:
        line = line.split(',')
        tmp = dataFromFile.objects.create()
        tmp.router_ip = line[0]
        tmp.neighbor_ip = line[1]
        tmp.as_num = line[2]
        tmp.save()
    f.close()

для обновления от выполнения скрипта он выдал ошибку

(env) bowbth@bowbth:~/django-apps/mysite$ python manage.py shell
Python 3.6.6 (default, Sep 12 2018, 18:26:19) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> exec(open('import_data_csv.py').read())
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "<string>", line 16, in <module>

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018
  • Создание API REST для приема списка записей для вставки
  • Напишите ваши сценарии очистки в представлении, которое обрабатывает запрос
  • Используйте пример сценария для чтения из CSV и формирования JSON, совместимого с API, и отправки запроса на конечную точку API с сформированным JSON в качестве данных
0 голосов
/ 09 ноября 2018

Вы можете создать свой собственный скрипт и запустить с помощью команды python manage.py shell:
Ваш скрипт должен быть примерно таким:

#!/usr/bin/env python

"""
    Script to import data from .csv file to Model Database DJango
    To execute this script run: 
                                1) manage.py shell
                                2) exec(open('file_name.py').read())
"""

import csv
from AppName.models import Model1, Model2 

CSV_PATH = '../../your_file_name.csv'      # Csv file path  


with open(CSV_PATH, newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=';', quotechar=';')
    for row in spamreader:
        Model.objects.create(... Attributes here ...)
        # Example -> Book.objects.create(ISBNCode=row[0], title=row[1], author=row[2])

Посмотрите на мой Пример в Github
С другой стороны, я рекомендую вам взглянуть на это Ответ , здесь вы найдете больше информации о том, как работает с .csv файлами в Джанго.

...