• (动态模型类,我的独创)Django的原生ORM框架如何支持MongoDB,同时应对客户使用时随时变动字段


    1.背景知识

      需要开发一个系统,处理大量EXCEL表格信息,各种类别。表格标题多变,因此使用不需要预先设计数据表结构的MongoDB,即NoSQL。一是字段不固定,二是同名字段可以存储不同的字段类型。

      同时,后端确定使用Django,原因是数据处理这一块,python无敌于天下。

      Django采用MVT模式开发。MODEL是最关键的部分。是ORM的核心。但是ORM主要用于关系型数据库。那么如何解决?

    2.大量调研的网上资料

    (1)mongoengine

        mongoengine(跟pymongodb类似,但是相比于后者,又能提供模型类的功能,封装一些数据操作,不用单独写一堆crub)

          缺点:经反复测试研究,不支持django的原生后台管理功能,因为无法将django的数据迁移到mongodb数据库中因此无法使用原生的后台管理界面,需要定制。

    (2)djongo(注意不是django。爹是django,妈是mongodb,交配出来的物种)

           

           与Django支持的其它SQL数据库类型,用于支持Nosql。

           可以将django的数据迁移到mongodb数据库中,也可以使用原生的后台管理界面

    (3)Django-nonrel

      django的分支,有时间可以研究一下。

    3.目前的问题(用mongodb仿ORM,那么如何随时变动字段?)

       OVM模型的重点就是提前定义类的成员,同时迁移到数据表中,形成相应字段。

            对于一个excel表,记录图书信息,比如,书名,出版日期。

            我们只需要用下述方式定义一个类,

    # 创建图书类
    class BookInfo(models.Model):
        """图书模型类"""
        # 图书名称,CharField说明是该类属性是一个字符串,max_length指定最大长度
        book_title = models.CharField(max_length=20)
    
        # 出版日期,DateField说明该类属性是一个日期
        book_pub_date = models.DateField()
    
        def __str__(self):
            """覆盖对BookInfo实例化对象使用str()的返回值"""
            return self.book_title  # 返回书名
    

      作为model放入django中。后面执行如下操作,数据库就可以相应的自动变化了。

           有djongo对django和mongodb支持,我们可以将mongodb“仿”为ORM模型,注意,是仿。

    def get(request):
        # book=BookInfo()
        # book.book_title='水浒传'
        # book.book_pub_date=date(1960,1,1)
        
        # book.save()
       #    return HttpResponse('helloworld')
    

      那么如何随时变动字段呢?比如,哪天使用方的excel表格又变动了,增加了一列,比如作者。那么如何将作者这个字段加入呢?同时,不改变原始代码?

    4.解决方案(动态模型类)

    (1)模型save的局限性

     首先,python支持类成员随时定义,我们直接在模型类对象中,添加一个成员。 
    # book.author = '罗贯中'
    但是发现模型的save操作,对这个临时增加的成员不处理,无法加入数据库中。
    save只处理在原始models.py文件中定义BookInfo的时候定义的固定类成员。
    通过调试发现,Django在运行前需要首先对各个models.py进行解析。因此,后续在模型类实例化对象中临时增加成员,是没用的。

    (2)我的方式:强制解析新的模型类,支持对字段进行变动,更好时候NoSQL

     通过文件定义的类,具有一些特殊字段。__module__ __qualname和__doc__

       由于Django只处理models.py文件中定义的模型类。所以,

       在程序执行时,动态创建新的模型类,并且修改其成员属性,把其仿真为文件中定义的模型类,然后再用django进行解析,使其能够作为ORM的新model。

       

    BookInfo = type('BookInfo', (models.Model,), {"__module__":"booktest.models",'__qualname__':'BookInfo',"__doc__":"注释", "book_title": models.CharField(max_length=20),"book_pub_date" :models.DateField(),"author": models.CharField(max_length=20)})
    book=BookInfo()
    book.book_title='三国演义xxx'
    book.book_pub_date=date(1960,1,1)
    book.author='我是杰少啊'
    book.save()

     注意两点:第一,由于内存中有原始模型类BookInfo,我们要对其完全覆盖掉。

       上面type为什么会触发django重新解析模型类呢?

       因为BookInfo继承的model,核心是继承Django的ModelBase类。当执行上述动态类定义过程时,就会触发解析。

       通过上述处理,我们就能实现对数据库插入作者字段了。数据库中内容如下:

       

  • 相关阅读:
    洛谷 P2234 [HNOI2002]营业额统计
    洛谷p3146&p3147
    洛谷 p1439 最长公共子序列
    搜索
    一步一步分析Caliburn.Micro(二:绑定执行方法Message现学现卖之自定命令)
    一步一步分析Caliburn.Micro(一:绑定执行方法Message)
    整理的C# 字符串类
    不用ADOX.CatalogClass创建Access数据库文件
    取远程网页数据 WebClient,HttpWebRequest
    C# LinQ 与 ADO.NET
  • 原文地址:https://www.cnblogs.com/xiaojieshisilang/p/16098411.html
Copyright © 2020-2023  润新知