在使用Django添加到数据库之前操作Excel数据 – 操作顺序?

我每周收到6份excel报告,我已经手动编写了一份非常大的月度报告。 每个报告有5-30列,4000到130,000行。

我在一个简单的Django应用程序,允许您上传每个报告,数据结束在数据库中。

这是我的models.py:

#UPEXCEL models from django.db import models ############## LISTS ############### class TransactionTypeList(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class TransactionAppTypeList(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class CrmCaseOriginList(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name ############## CLIENTS AND STAFF ############### class Staff(models.Model): name = models.CharField(max_length=40) employee_id = models.CharField(max_length=40) start_date = models.TimeField(blank=True, null=True) end_date = models.DateField(blank=True, null=True) first_name = models.CharField(blank=True, null=True, max_length=40) last_name = models.CharField(blank=True, null=True, max_length=40) email = models.EmailField(blank=True, null=True) phone = models.CharField(blank=True, null=True, max_length=20) street = models.CharField(blank=True, null=True, max_length=100) city = models.CharField(blank=True, null=True, max_length=100) state = models.CharField(blank=True, null=True, max_length=2) zipcode = models.CharField(blank=True, null=True, max_length=10) is_team_lead = models.BooleanField(default=False) boss = models.ForeignKey('Staff', related_name='Boss', null=True, blank=True) def __str__(self): return self.name class Meta: app_label="upexcel" class Client(models.Model): name = models.CharField(max_length=40) short_name = models.CharField(max_length=20, blank=True, null=True) start_date = models.DateField(default=timezone.now, blank=True, null=True) end_date = models.DateField(blank=True, null=True) team_lead = models.ForeignKey(Staff, related_name='client_team_lead') def __str__(self): return self.name class ClientNameChart(models.Model): client_name = models.ForeignKey(Client, related_name='client_corrected_name') name_variation = models.CharField(max_length=100) date_added = models.DateTimeField(auto_now_add=True) def __str__(self): return '%s becomes %s' % (self.name_variation, self.client_name) class StaffNameChart(models.Model): staff_name = models.ForeignKey(Staff, related_name='staff_corrected_name') name_variation = models.CharField(max_length=100) date_added = models.DateTimeField(auto_now_add=True) def __str__(self): return '%s becomes %s' % (self.name_variation, self.staff_name) ############## DATA FROM REPORTS ############### class CrmNotes(models.Model): created_by = models.ForeignKey(Staff, related_name='note_creator') case_origin = models.CharField(max_length=20) client_regarding = models.ForeignKey(Client, related_name='note_client_regarding') created_on = models.DateTimeField() case_number = models.CharField(max_length=40) class Transactions(models.Model): client_regarding = models.ForeignKey(Client, related_name='transaction_client') created_by = models.ForeignKey(Staff, related_name='transaction_creator') type = models.ForeignKey(TransactionTypeList, related_name='transaction_type') app_type = models.ForeignKey(TransactionAppTypeList, related_name='transaction_app_type') class Meta: app_label="upexcel" class Timesheets(models.Model): staff = models.ForeignKey(Staff, related_name='staff_clocked_in') workdate = models.DateField() start_time = models.DateTimeField() end_time = models.DateTimeField() total_hours = models.DecimalField(decimal_places=2, max_digits=8) class Provider(models.Model): name = models.CharField(max_length=40) street = models.CharField(max_length=100) city = models.CharField(max_length=40) state = models.CharField(max_length=11) zip = models.CharField(max_length=10) class StudentsApplication(models.Model): app_number = models.CharField(max_length=40) program = models.CharField(max_length=40) benefit_period = models.CharField(max_length=40) student_name = models.CharField(max_length=40) student_empl_id = models.CharField(max_length=40) requested_amount = models.DecimalField(max_digits=8, decimal_places=2) provider = models.ForeignKey(Provider, related_name='app_provider') provider_code = models.CharField(max_length=40) class AuditReport(models.Model): was_audited = models.BooleanField(default=False) auditor = models.ForeignKey('upexcel.Staff', related_name='auditor') payment_defect = models.BooleanField(default=False) grant_discount_error = models.BooleanField(default=False) math_error = models.BooleanField(default=False) fees_book_error = models.BooleanField(default=False) other_error = models.BooleanField(default=False) overpayment_amount = models.DecimalField(max_digits=8, decimal_places=2) underpayment_amount = models.DecimalField(max_digits=8, decimal_places=2) doc_defect = models.BooleanField(default=False) status_change = models.BooleanField(default=False) admin_savings_defect = models.BooleanField(default=False) network_savings_defect = models.BooleanField(default=False) admin_adjustments = models.DecimalField(max_digits=8, decimal_places=2) network_adjustments = models.DecimalField(max_digits=8, decimal_places=2) error_corrected = models.BooleanField(default=False) comments = models.TextField(max_length=500) client = models.ForeignKey(Client, related_name='audited_client') staff = models.ForeignKey(Staff, related_name='processor_audited') application = models.ForeignKey(StudentsApplication, related_name='app_audited') class Meta: app_label="upexcel" 

然而,我正在采取的Excel报告需要做一些工作,我想弄清楚我应该如何去处理和路由他们。

第一个挑战是每个报告都用不同的数据引用相关的员工和客户。 例如,如果Staff.name是“Bob Dole”,则一个报告将其命名为“Dole,Bob”。 另一个是“Dole,Robert”。 还有一个是“罗伯特·多尔”,然后是“103948210”,这是他的员工身份证号码。

此外,这些变化和新的发展,这就是为什么我做ClientNameChart和StaffNameChart,用户可以inputstring,如在报告中显示,并将其附加到客户端或工作人员。 然后在处理时,我们可以查找StaffNameChart.name_variation,并返回关联的StaffNameChart.Staff.employee_id,这应该在各自报表的表格(即AuditReport.staff)中作为外键使用,

第二个挑战是采取一个报告,并将一些列路由到一个数据库表,另一个到另一个。 例如,最大的是审计报告表。 许多列只是直接转置到AuditReport(models.Model)中。 但是,它也有每个StudentsApplication和Provider的数据,我需要取几列,将它们作为新的logging存储在目标表中,然后用包含该目标表中该项目的外键的列replace。

所以这是我的追求。

这里是我脑海中的操作顺序 – 我将使用最复杂的Audit_Report_Wk_1.xlsx报告来解决一次上传中的所有挑战:

  1. 上传文件
  2. 使用openpyxl,加载只读数据:

     from openpyxl.worksheet.read_only import ReadOnlyWorksheet myexcelfile = request.FILES['file'] myworkbook = load_workbook(myexcelfile, read_only=True) mysheet = myworkbook['Sheet1'] 
  3. 使用StaffNameChart.name_variation编写一个脚本,用于匹配staff, StaffNameChart.name_variation和client列的名称string,并用StaffNameChart.name_variationreplace它。

  4. B部分:如果客户或员工列是空白的,或者包含在名称图表中找不到的string,所有这些行都保存在一个新的Excel文档中。 编辑:我想我也可以创build一个名为IncompleteAuditReport的新模型类,它只包含与每列匹配的字段并将其存储在那里,然后如果有人添加了一个新的NameChart变体,它可能会触发一个快速查找,看看是否可以允许这个过程完成,并且logging被正确添加?)
  5. 检查mysheet中将被ProviderStudentsApplication Provider的外键replace的列。 如果它们各自的数据不存在于它们各自的表中,则添加新的logging。 无论哪种方式,然后用指向结果logging的外键replace它们的列。

这是正确的操作顺序吗? 任何有关使用openpyxl等特定工具以最有效的方式处理数据的build议,所以我可以使用最less的资源查找,然后更改数十万个字段?

如果你读了这么多,非常感谢 。 我现在对更复杂的数据types有点恐惧,所以我不清楚数据存储在内存中的最佳方式,并在它存在的时候操纵它。