Есть ли эффективный способ добавить файл csv с большим количеством столбцов в модель Django?

У меня есть фрейм данных с более чем 150 столбцами, которые я хочу добавить в свою базу данных Django. Все, что я видел в Интернете, дает пример использования только пары столбцов и требует, чтобы вы перечислили каждое поле, которое вы хотите использовать. Есть ли способ создать модель, которая наследует столбцы фрейма данных и выполняет этот процесс более эффективно?

<

Вот лучшие способы работы с динамическими данными

JSONField - это здорово, но, возможно, лучше иметь более строгую схему БД с фиксированными колонками, особенно если вы собираетесь использовать возможности Django queryset (фильтрация и т.д.) для данных в колонках. В этом случае вам придется так или иначе создать модель со 150 полями. Учитывая фрейм данных, вы можете сгенерировать раз и навсегда строки полей вашей модели:

for name in df.columns:
    print("    %s = models.FloatField('%s')" % (name, name))

Затем просто скопируйте-вставьте результат в определение вашей модели Django, например:

class YourModel(models.Model):
    a = models.FloatField('a')
    b = models.FloatField('b')
    c = models.FloatField('c')
    ...

Теперь давайте рассмотрим импорт данных:

Если фрейм данных является доверенным, а столбцы названы с тем же синтаксисом, что и имена полей вашей модели (хорошо, например, когда просто импортируется фрейм данных, используемый для создания модели), вы можете сделать:

YourModel.objects.bulk_create([
    YourModel(**row) for _, row in df.iterrows()
])

row по сути является диктоподобным объектом, поэтому, если столбцы - это "a", "b" и "c", row может быть похож на что-то вроде {'a': 10, 'b': 11, 'c': 12}, что делает вызов YourModel похожим на YourModel(a=10, b=11, c=12).

Если фрейму данных нельзя доверять, например, если пользователи могут каким-то образом "загружать фреймы данных", чтобы заставить БД расти, каждый новый входной фрейм данных должен быть проверен:

  1. (Важно; для предотвращения инъекции именованных параметров в YourModel.) Проверьте, что имена столбцов соответствуют вашим ожиданиям. Если вы не хотите жестко кодировать ожидаемые имена столбцов, проверьте, что каждое имя существует в модели Django, например, добавив это перед кодом выше:

    >
    valid_names = [f.name for f in YourModel._meta.get_fields()]
    if not all(name in valid_names for name in df.columns):
        raise ...
    
  2. Проверить данные строки.

В реальном мире я рекомендую делать 1. даже если вы доверяете данным. Это может сэкономить время в дальнейшем, поскольку позволит отловить непреднамеренные ошибки, если код, используемый для генерации кадров данных, изменится.

Вернуться на верх