【问题标题】:Import unstructured excel file to database将非结构化的excel文件导入数据库
【发布时间】:2018-03-28 15:26:15
【问题描述】:

我必须将数据从 excel 文件导入数据库。 这些文件的结构与模型的结构不匹配,所以我想我需要做一些数据操作来相应地安排元组。

我必须导入的文件如下所示:

django-model 有以下属性:Country, Commodity, Year, Value

那么读取数据的最佳方式是什么,以正确的结构排列数据并将其导入数据库(最好自动更新现有元组)。

我花了很多时间研究现有的 python 和 django 库来满足这个要求(如 PyExcel、Pandas、Django-Excel、Django-Import-Export),但我真的不知道哪个是最好的以及是否支持在导入前重新排列数据。

希望你能给我一些关于这个任务的建议和解决方案:)

【问题讨论】:

  • 什么是“数据库”?您只是将文件上传到数据库,还是必须进行某种分析?到目前为止,您尝试过什么?
  • @Evan 我只想从文件中获取数据到数据库中,不需要分析。但如上所述,我需要手动调整结构,因为数据集不是每年分开的。基本上我认为一些库允许我将 excel 数据读入数据结构(数组或字典),然后编辑/调整这个数组,然后将它输入到数据库中是最好的。不幸的是,我没有从任何提到的库中找到有关此的信息。
  • 根据您的说法,我建议使用 pandas 库及其 read_excel() 函数。您可以创建数据框,对其进行操作,然后将其输出到 CSV 或数据库(例如 SQL),但如果您不告诉我们您的数据库是什么,我们将无法帮助您。
  • @Evan 好的,我会查一下。该数据库是带有 django 模型的 PostgreSQL。数据库对我如何实现功能有影响吗?

标签: python django pandas pyexcel django-excel


【解决方案1】:

好的,有几件事。请注意,我不是其中任何一个方面的专家。

首先,如果您的数据是 Excel 文件,则它是结构化的。表的本质是结构化数据。非结构化数据类似于文本文件或文本文件目录。

其次,请阅读本文并在提出问题时关注它:https://stackoverflow.com/help/mcve

第三,SO 不是来为您编写所有代码的。根据您的问题,您尚未尝试任何事情,这就是您的问题被否决的原因。

撇开序言不谈,您可以使用 Python 的 pandas 库来导入 Excel 文件、操作它们并将它们上传到 SQL 数据库。

import pandas as pd

df = pd.read_excel('tmp.xlsx')
df2 = pd.melt(df, id_vars = ['Country', 'Commodity'], var_name = 'Year', value_name = 'Value')
df2

输入:

    Country Commodity  2009  2010  2011  2012  2013
0  Austria    Com. 1     1     1     1     1     1
1  Austria    Com. 2     2     2     2     2     2
2  Belgium    Com. 1     3     3     3     3     3
3   France    Com. 1     4     4     4     4     4

输出:

   Country Commodity  Year  Value
0  Austria    Com. 1  2009      1
1  Austria    Com. 2  2009      2
2  Belgium    Com. 1  2009      3
3   France    Com. 1  2009      4
4  Austria    Com. 1  2010      1

如果您有许多 Excel 文件,您可以使用 globos.walk 遍历/遍历目录,并导入部分或全部 Excel 文件。

您可以使用 pandas DataFrame.to_sql 将您的数据上传到 SQL 数据库,这需要定义数据库连接(服务器地址、登录名/密码等)。

【讨论】:

  • 谢谢,到目前为止工作正常。不幸的是,我偶然发现了另一个问题:excel文件的末尾有一些我想跳过的信息。但是,这些行的数量因文件而异。此信息的开头由具有特定关键字的行标识。我研究了很多关于 pandas 的索引以及如何跳过/删除某些行的信息,但我找不到以下信息:如何跳过/删除从特定行开始的所有行?
  • 这是一种非常适合其自己的线程 Stack Overflow 的特定问题,特别是如果您无法在现有问题中找到答案。也就是说,我用几秒钟的谷歌搜索找到了几个:chrisalbon.com/python/pandas_selecting_rows_on_conditions.htmlstackoverflow.com/questions/27275236/…reddit.com/r/learnpython/comments/5zn29l/…
【解决方案2】:

这是使用一个外键插入的示例。

    models.py

        from django.db import models

        class Table1(models.Model):
            system = models.CharField(max_length=383)

        class Table2(models.Model):
            name = models.CharField(max_length=383)
            system = models.ForeignKey(Table1, blank=True, null=True, on_delete=models.CASCADE)

您需要创建一个 modelResource 并覆盖 before_import_row 以便在 table1 中插入数据。您可以更改字段名称并创建表格和自定义。 'column_name'是excel数据中的字段名,属性是数据库中的字段名。在 nefore_import 方法中,您可以在表中插入数据并分配外键。

并将 ModelResource 设置为管理类。

    admin.py
        from .models import Table1,Table2
        from import_export import resources,widgets
        from import_export.fields import Field
        from django.contrib import admin


        class Table2Resource(resources.ModelResource):
            name = Field(column_name='name',attribute='name')
            system_id = Field(column_name='system', attribute='system_id', widget=widgets.ForeignKeyWidget(Table1))

            class Meta:
                model = Table2
                skip_unchanged = True
                fields = ('name','system_id')

            def before_import_row(self,row, **kwargs):
                value = row['system']
                obj = Table1.objects.create(system = value) #create object place
                row['system'] = obj.id # update value to id ob new object


        @admin.register(Table2)
        class Table2Admin(ImportExportModelAdmin,admin.ModelAdmin):
            resource_class = Table2Resource

这就是全部。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-18
    相关资源
    最近更新 更多