我想从文本文件中读取数据并将其保存到Django中的数据库中

时间:2018-11-10 02:01:29

标签: python django

我是DjangoPython的新手。我想从文本文件中读取数据并将其保存到database

输入文件示例:

E Alan Marshall 121 55.26 
E Bob Marley 122 66.78
M Ted Smith Marketing 123 76.78 
M Ron Barly Production 124 86.78

我对models的描述如下:

class Employee(models.Model):   
        first = models.CharField(max_length=20)
        last = models.CharField(max_length=20)
        id = models.IntegerField()
        pay = models.DecimalField(max_digits=12, decimal_places=2)

class Manager(models.Model):
        first = models.CharField(max_length=20)
        last = models.CharField(max_length=20)
        department = models.CharField(max_length=20)
        id = models.IntegerField()
        pay = models.DecimalField(max_digits=12, decimal_places=2)  

我以文本文件的形式接收数据,并通过解析字符串读取数据。第一个字符告诉我期望的类数据的类型(例如E表示员工类对象数据,M表示经理类对象数据) 一旦我们知道了数据的类型,变量发生的顺序就固定了。意味着如果我用'space'作为定界符标记字符串,对于Employee类,第一个元素是名字,下一个是姓氏,下一个是雇员id,下一个是薪金

我想用python编写代码,该代码将解析输入文件并创建相应类的对象。 我也应该保持类变量的类型

type of
            first is string
            last is string
            id is interger
            pay is float
            department is string

我打算编写通用函数来解析和创建类的对象。 它将逐行读取文件,对行进行标记并调用函数以生成类的对象。 "generateClassObject"函数将以变量名及其类型的字典作为输入。 (例如,Employee class {"first":"string", "last":"string", "id":"integer", "pay":"float" },经理class {"first":"string", "last":"string", "department":"string" "id":"integer", "pay":"float" }) 并返回类对象。

该函数看起来像

generateClassObject(className, dictionary, tokenizedData):
    # instantiate class object based on className (How to do this?)
    # read dictionary one by one and assign value to respective variable of
      # class object from tokenizedData by converting string data to proper
      # type (How to do this?)
    # save class object to database (I know how to do this)

是否可以在dynamically中创建类python的对象? 如何基于className实例化类对象? 如果我们知道python中适当的数据类型,如何将字符串数据转换成适当的数据类型?

3 个答案:

答案 0 :(得分:1)

您可以创建一个类方法。

class Employee(models.Model):   
        first = models.CharField(max_length=20)
        last = models.CharField(max_length=20)
        id = models.IntegerField()
        pay = models.DecimalField(max_digits=12, decimal_places=2)

        @classmethod
        def from_file(cls, line):
            # parse line of input here
            emp = cls.create(first=first, last=last, id=id, pay=pay)
            return emp

# code to read from file
line = file.readline()
if line.startswith("E"): 
    bob = Employee()
    bob.from_file(line)
    # add code to save to database

进一步阅读:https://docs.djangoproject.com/en/2.1/ref/models/instances/

答案 1 :(得分:0)

首先,我会严重质疑您为什么即使经理和员工都有相同的字段也有单独的模型。最好有一个带有role字段的单一模型。

不过,如果您确实要执行此操作,则只需要保留一个将代码映射到模型的字典即可。

models = {
    'E': Employee,
    'M': Manager
}
instance = models[class_name].objects.create(**params)

答案 2 :(得分:0)

我会接受@DanielRoseman的推荐。但是对于从文本文件

开始的一般答案
import re
from project.models import CorporatePerson
with open('input_file.txt') as ifile:
    s = ifile.readline()
    m = re.search('([E,M]) (.{1,}) (.{1,}) (.{1,}) (.{1,}) (.{1,})', s)
    CorporatePerson.objects.create(
    role=m.group(0)
    first =m.group(1)
    department=m.group(2)
    id=m.group(3)
    pay=m.group(4)
    )

这要求您为输入文件中的每个nonedepartment添加employee之类的内容。

如果您要坚持使用2个模型,则可以使用if语句来将其保存到EmployeeManager模型中,然后将每个模型与它们的模型匹配拥有regex,但您明白了...

我知道这并不会像您在帖子中提到的那样进行分词处理,但这提供了一个更容易编写(并且可能更快捷,更脏的解决方案),并且非常容易编写和更改。

如果这是您要使用并反复适应的工具,那么我将创建一个类,该类可以消化文本文件,该文本文件的属性(或列)数量可能有所不同