我每周收到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”。还有一个是“Robert Dole”,然后是“103948210”,这是他的员工ID号。
此外,这些更改和新的更改,这就是我将ClientNameChart和StaffNameChart设置为用户可以输入报表中显示的字符串并将其附加到客户端或工作人员的原因。然后在处理时,我们可以查找StaffNameChart.name_variation,并返回关联的StaffNameChart.Staff.employee_id,它应该在相应报表的表中作为外键工作(即.ReportReport.staff)
第二个挑战是采取报告,并将一些列路由到一个数据库表,将其他列路由到另一个数据库表。例如,最重要的是审计报告表。许多列只是直接转换到AuditReport(models.Model)。但是,它还包含每个StudentsApplication和Provider的数据,其中我需要获取多个列,将它们作为新记录存储在其目标表中,并将列替换为包含该目标表中该项的外键的一列。
这就是我的追求。
以下是我脑海中的操作顺序 - 我将使用最复杂的Audit_Report_Wk_1.xlsx报告来解决一次上传中的所有挑战:
使用openpyxl,加载只读数据:
from openpyxl.worksheet.read_only import ReadOnlyWorksheet
myexcelfile = request.FILES['file']
myworkbook = load_workbook(myexcelfile, read_only=True)
mysheet = myworkbook['Sheet1']
编写一个与StaffNameChart.name_variation
的员工,审核员和客户列的名称字符串相匹配的脚本,并将其替换为StaffNameChart.Staff.name
。
IncompleteAuditReport
的新模型类,其中只有与每列匹配的字段并将其存储在那里,然后如果有人添加了新的NameChart变体,它可以触发快速查找看看是否可以完成此过程并正确添加记录?)mysheet
中将被Provider
和StudentsApplication
标签的外键替换的列。如果各自的表中尚不存在各自的数据,请添加新记录。无论哪种方式,然后用指向结果记录的外键替换它们的列。这是正确的操作顺序吗?有关使用openpyxl等使用哪些特定工具以最有效的方式操作数据的建议,所以我可以使用最少的资源来查找然后更改几十万个字段?
非常感谢你,如果你已经阅读了这篇。我现在对更复杂的数据类型感到有点害怕,所以对我来说,最好的方法是将数据存储在内存中并在内存中进行操作时,这一点并不十分清楚。