як імпортувати дані CSV в моделі django -


79

У мене є деякі дані CSV, і я хочу імпортувати їх у моделі django, використовуючи приклади даних CSV:

1;"02-01-101101";"Worm Gear HRF 50";"Ratio 1 : 10";"input shaft, output shaft, direction A, color dark green";
2;"02-01-101102";"Worm Gear HRF 50";"Ratio 1 : 20";"input shaft, output shaft, direction A, color dark green";
3;"02-01-101103";"Worm Gear HRF 50";"Ratio 1 : 30";"input shaft, output shaft, direction A, color dark green";
4;"02-01-101104";"Worm Gear HRF 50";"Ratio 1 : 40";"input shaft, output shaft, direction A, color dark green";
5;"02-01-101105";"Worm Gear HRF 50";"Ratio 1 : 50";"input shaft, output shaft, direction A, color dark green";

У мене є кілька моделей django з назвою Product. У Product є кілька полів, таких як name, descriptionі price. Я хочу щось подібне:

product=Product()
product.name = "Worm Gear HRF 70(02-01-101116)"
product.description = "input shaft, output shaft, direction A, color dark green"
product.price = 100

1
< docs.python-tablib.org/en/latest/index.html > - також чудова бібліотека для цього.
Крейг Лабенц,

Відповіді:


87

Ви хочете використовувати модуль csv, який є частиною мови python, і ви повинні використовувати метод get_or_create Django

 with open(path) as f:
        reader = csv.reader(f)
        for row in reader:
            _, created = Teacher.objects.get_or_create(
                first_name=row[0],
                last_name=row[1],
                middle_name=row[2],
                )
            # creates a tuple of the new object or
            # current object and a boolean of if it was created

У моєму прикладі викладач моделі має три атрибути ім'я, прізвище та ім'я по батькові.

Документація Django щодо методу get_or_create


Дякую за відповідь. Щоб лише додати, не забудьте пропустити рядок заголовка, якщо він є. Якщо його не ігнорувати, це може призвести до таких важких для налагодження помилок, як ця: stackoverflow.com/questions/43114679/…
Анупам,

2
Просто для того, щоб додати до цього, я зробив це за допомогою команди управління та зміг запустити імпорт за допомогою django manage.py:python manage.py loadgamecsv CSV_PATH
Рокко,

Так за відповідь. Я судима реалізувати його в .py скрипт Незалежні, але потім я біжу в цю проблему stackoverflow.com/a/58322333/7658051
Tms91

34

Якщо ви хочете скористатися бібліотекою, швидкий пошук csvі виявлення в Google djangoдвох бібліотек - django-csvimport та django-adapters . Давайте прочитаємо, що вони мають сказати про себе ...

  • django-адаптери :

Адаптер Django - це інструмент, який дозволяє легко перетворити файл CSV / XML у об'єкт python або екземпляр моделі django.

  • django-importcsv :

django-csvimport - це загальний інструмент імпортера, який дозволяє завантажувати файли CSV для заповнення даних.

Перший вимагає написання моделі, яка відповідає файлу csv, тоді як другий - скоріше імпортер командного рядка, що є величезною різницею у роботі з ними, і кожна з них підходить для іншого типу проектів.

То який із них використовувати? Це залежить від того, хто з них буде більш підходящим для вашого проекту в довгостроковій перспективі.

Однак ви також можете зовсім уникнути бібліотеки, написавши власний скрипт django, щоб імпортувати ваш файл csv, щось на зразок (попередження, псевдокод вперед):

# open file & create csvreader
import csv, yada yada yada

# import the relevant model
from myproject.models import Foo

#loop:
for line in csv file:
     line = parse line to a list
     # add some custom validation\parsing for some of the fields

     foo = Foo(fieldname1=line[1], fieldname2=line[2] ... etc. )
     try:
         foo.save()
     except:
         # if the're a problem anywhere, you wanna know about it
         print "there was a problem with line", i 

Це надзвичайно просто. Чорт, це можна зробити інтерактивно через оболонку django, якщо це одноразовий імпорт. Просто - з’ясуйте, що ви хочете зробити зі своїм проектом, скільки файлів вам потрібно обробити, а потім - якщо ви вирішите скористатися бібліотекою, спробуйте з’ясувати, який із них краще відповідає вашим потребам .



2
@ Shog9 Я тільки зараз це помітив. Я не розумію, чому? ці два запитання взагалі не пов’язані, і це перетворює всю мою відповідь на безглузде пояснення чогось зовсім іншого, ніж те, про що вимагає ОП. Чи не слід його об’єднати навпаки?
юві

Обидва питання стосуються однієї і тієї ж проблеми, але це краще питання з точки зору надання прикладу іншим. Якщо ви не проти редагування, я думаю, що ваша відповідь може бути тут корисною.
Shog9

@ Shog9 добре, я бачу вашу думку. Я не проти редагування, я доберусь до нього, коли зможу. Дякую за відповідь
yuvi

13
"швидкий пошук у Google для CSV та Django" ... перевів мене на цю сторінку :-p
Кріс Хуанг-Лівер 02

8

Бібліотека CSV Python може виконувати ваш синтаксичний аналіз, а ваш код може їх перекладати Products().


8

Ви також можете використовувати django-адаптери

>>> from adaptor.model import CsvModel
>>> class MyCSvModel(CsvModel):
...     name = CharField()
...     age = IntegerField()
...     length = FloatField()
...
...     class Meta:
...         delimiter = ";"

Ви заявляєте MyCsvModel, який збігатиметься з файлом CSV таким чином:

Антоній; 27; 1,75

Щоб імпортувати файл або будь-який об’єкт, що підлягає ітерації, просто виконайте:

>>> my_csv_list = MyCsvModel.import_data(data = open("my_csv_file_name.csv"))
>>> first_line = my_csv_list[0]
>>> first_line.age
    27

Без явного оголошення дані та стовпці узгоджуються в однаковому порядку:

Anthony --> Column 0 --> Field 0 --> name
27      --> Column 1 --> Field 1 --> age
1.75    --> Column 2 --> Field 2 --> length

Чи знаєте ви метод виправлення запису аргументу оновлення в класі Meta всередині моєї Csvmodel? Я намагаюся це зробити, але отримав KeyError.
Крістіан Рохас

8

Використовуйте бібліотеку Pandas для створення фрейму даних із даних csv.
Назвіть поля, включивши їх у перший рядок файлу csv, або в код, використовуючи метод стовпців фрейму даних.
Потім створіть список екземплярів моделі.
Нарешті, скористайтеся методом django .bulk_create (), щоб надіслати свій список примірників моделі до таблиці бази даних.

Функція read_csv у пандах чудово підходить для читання файлів csv і дає вам безліч параметрів для пропуску рядків, пропуску полів тощо.

import pandas as pd

tmp_data=pd.read_csv('file.csv',sep=';')
#ensure fields are named~ID,Product_ID,Name,Ratio,Description
#concatenate name and Product_id to make a new field a la Dr.Dee's answer
products = [
    Product(
        name = tmp_data.ix[row]['Name'] 
        description = tmp_data.ix[row]['Description'],
        price = tmp_data.ix[row]['price'],
    )
    for row in tmp_data['ID']
]
Product.objects.bulk_create(products)

Я використовував відповідь mmrs151, але зберігати кожен рядок (екземпляр) було дуже повільно, і будь-які поля, що містять розмежувальний символ (навіть усередині лапок), не оброблялись методом open () - line.split (';').

У панди так багато корисних застережень, що варто ознайомитися з ними


На мою думку, використання панд для завантаження даних є надмірним.
П.Панайотов

8

Для django 1.8, який я використовую,

Я зробив команду, згідно з якою ви зможете динамічно створювати об’єкти в майбутньому, тому ви можете просто вказати шлях до файлу csv, ім’я моделі та ім’я програми відповідного django-додатку, і воно заповнить відповідну модель без вказаного поля імена. так що якщо взяти для прикладу наступний csv:

field1,field2,field3
value1,value2,value3
value11,value22,value33

він створить об’єкти [{field1: value1, field2: value2, field3: value3}, {field1: value11, field2: value22, field3: value33}] для імені моделі, яку ви введете до команди.

код команди:

from django.core.management.base import BaseCommand
from django.db.models.loading import get_model
import csv


class Command(BaseCommand):
    help = 'Creating model objects according the file path specified'

    def add_arguments(self, parser):
        parser.add_argument('--path', type=str, help="file path")
        parser.add_argument('--model_name', type=str, help="model name")
        parser.add_argument('--app_name', type=str, help="django app name that the model is connected to")

    def handle(self, *args, **options):
        file_path = options['path']
        _model = get_model(options['app_name'], options['model_name'])
        with open(file_path, 'rb') as csv_file:
            reader = csv.reader(csv_file, delimiter=',', quotechar='|')
            header = reader.next()
            for row in reader:
                _object_dict = {key: value for key, value in zip(header, row)}
                _model.objects.create(**_object_dict)

зверніть увагу, що, можливо, в пізніших версіях

from django.db.models.loading import get_model

застаріло і його потрібно змінити на

from django.apps.apps import get_model

7

щось на зразок цього:

f = open('data.txt', 'r')  
for line in f:  
   line =  line.split(';')  
   product = Product()  
   product.name = line[2] + '(' + line[1] + ')'  
   product.description = line[4]  
   product.price = '' #data is missing from file  
   product.save()  

f.close()  

4

Ви можете використовувати пакет django-csv-importor. http://pypi.python.org/pypi/django-csv-importer/0.1.1

Це працює як модель джанго

MyCsvModel(CsvModel):
    field1 = IntegerField()
    field2 = CharField()
    etc

    class Meta:
        delimiter = ";"
        dbModel = Product

І вам просто потрібно: CsvModel.import_from_file ("мій файл")

Це автоматично створить ваші продукти.


4
django-csv-
importor

4

Якщо ви працюєте з новими версіями Django (> 10) і не хочете витрачати час на написання визначення моделі. Ви можете скористатися інструментом ogrinspect.

Це створить визначення коду для моделі.

python manage.py ogrinspect [/path/to/thecsv] Product

Результатом буде визначення класу (моделі). У цьому випадку модель буде називатися Product . Вам потрібно скопіювати цей код у файл models.py.

Потім вам потрібно перенести (у оболонці) нову таблицю Product з:

python manage.py makemigrations
python manage.py migrate

Більше інформації тут: https://docs.djangoproject.com/en/1.11/ref/contrib/gis/tutorial/

Зверніть увагу, що приклад зроблено для ESRI Shapefiles, але він досить добре працює і зі стандартними файлами CSV.

Для проковтування ваших даних (у форматі CSV) ви можете використовувати панди.

import pandas as pd
your_dataframe = pd.read_csv(path_to_csv)
# Make a row iterator (this will go row by row)
iter_data = your_dataframe.iterrows()

Тепер кожен рядок потрібно перетворити на словник і використовувати цей дикт для створення інстанції вашої моделі (в даному випадку Product ())

# python 2.x
map(lambda (i,data) : Product.objects.create(**dict(data)),iter_data

Готово, перевірте базу даних зараз.


2

Ви можете спробувати django-import-export . Він має приємну інтеграцію адміністратора, попередній перегляд змін, може створювати, оновлювати, видаляти об’єкти.



Це дуже просто встановити та налаштувати, і, крім усього, він може читати не лише csv, а й xlsx, xls, ecc .. Це дійсно корисно, оскільки імпорт даних із CSV, ймовірно, не вдасться, якщо його текст має спеціальні символи.
Tms91

2

Це базується на відповіді Еріка з попереднього періоду , але мені було найпростіше прочитати у файлі .csv за допомогою панд, а потім створити новий екземпляр класу для кожного рядка у фреймі даних.

Цей приклад оновлено з використанням, ilocоскільки pandasбільше не використовує ix у найновішій версії. Я не знаю про ситуацію Еріка, але вам потрібно створити список за межами циклу for, інакше він не буде додаватися до вашого масиву, а просто перезапише його.

import pandas as pd
df = pd.read_csv('path_to_file', sep='delimiter')
products = []
for i in range(len(df)):
    products.append(
        Product(
        name=df.iloc[i][0]
        description=df.iloc[i][1]
        price=df.iloc[i][2]
        )
    )
Product.objects.bulk_create(products)

Це просто розбиття DataFrame на масив рядків, а потім виділення кожного стовпця з цього масиву за нульовим індексом. (тобто ім'я - це перший стовпець, опис - другий тощо)

Сподіваюся, що це допомагає.



1

Подумайте про використання вбудованих десенсіалізаторів Django. Документи Django добре написані і можуть допомогти вам розпочати роботу. Подумайте про перетворення даних із csv у XML або JSON та використання десериалізатора для імпорту даних. Якщо ви робите це з командного рядка (а не через веб-запит), команда loaddatamanage.py буде особливо корисною.



1

визначити клас у models.py та функцію в ньому.

class all_products(models.Model):
    def get_all_products():
        items = []
        with open('EXACT FILE PATH OF YOUR CSV FILE','r') as fp:
            # You can also put the relative path of csv file
            # with respect to the manage.py file
            reader1 = csv.reader(fp, delimiter=';')
            for value in reader1:
                items.append(value)
        return items

Ви можете отримати доступ до i-го елементу у списку як елементи [i]

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.