数据模型 - mongodb

2018-01-20  本文已影响0人  马梦里

在函数中的使用:


基类主要实现连接数据库和增删查改的作用,相当于是操纵数据库

import time
from bson import ObjectId
from pymongo import MongoClient

class Model(object):
    # 类变量,类里面可以通过 self 或 cls 调用
    db = MongoClient()['web21_1']

    @classmethod
    def valid_names(cls):
        names = [
            # (字段名, 类型, 默认值)
            ('deleted', bool, False),
            ('created_time', int, 0),
            ('updated_time', int, 0),
        ]
        return names

    def __repr__(self):
        class_name = self.__class__.__name__
        properties = ('{0} = {1}'.format(k, v) for k, v in self.__dict__.items())
        return '<{0}: \n  {1}\n>'.format(class_name, '\n  '.join(properties))

mongodb 字段的定义

    @classmethod
    def new(cls, form, **kwargs):
        m = cls()

        for name in cls.valid_names():
            k, t, v = name
            if k in form:
                setattr(m, k, t(form[k]))
            else:
                setattr(m, k, v)

        for k, v in kwargs.items():
            if hasattr(m, k):
                setattr(m, k, v)
            else:
                raise KeyError

        timestamp = int(time.time())
        m.created_time = timestamp
        m.updated_time = timestamp

        m.save()
        return m

增:
  一般增加评论、发表文章都是以表单方式发送数据,所以这里设置了个参数 form,可以直接将接收的数据拿过来用。当 form 的数据不够时,还可以通过参数 **kwargs 来增加;

  1. 第一个 for 循环用于解析表单发送的数据,将数据保存至类:
    • name代表字段,元祖,三个元素(k, t, v)对应键、类型、值。
    • if k in form:这种方式判断字典的键;
    • setattr(m, k, v),用于设置属性值,设置 m 的属性 k 为 v
  2. 第二个 for 循环用于解析手动传递的数据
    • hasattr(m, k) 用于判断 m 是否存在属性 k
  3. 最后,将自动生成的属性赋值(基本是时间)
    放在 new() 函数这里,是因为每个数据创建时,才会生成时间。如果放在基类属性那里,那么每次调用类方法的时候,时间都会被改变为当前事件。
  4. 调用 save() 方法保存至数据库
    def save(self):
       name = self.__class__.__name__
       _id = self.db[name].save(self.__dict__)
       self.id = str(_id)
    
  5. 保存至数据库:
    • name 获取子类名
    • 保存至类名对应的表
    • 将属性转换为字典形式保存
    • self.id = str(_id)
      这个属性并不会保存至数据库,是保存之后再设置的,目的在于替换 _id,因为 id_id 好看;而且 id 是字符串类型,'_id' 是 ObjectId 类型。
    @classmethod
    def delete(cls, id):
        name = cls.__name__
        query = {
            '_id': ObjectId(id),
        }
        values = {
            '$set': {
                'deleted': True
            }
        }
        cls.db[name].update_one(query, values)

删:
  这是一个假删除,每组数据都有个 delete 字段,初始值都是 false;假删除后,delete 的值变为 false。假删除并不会真正删除数据,只是显示的时候会排除这些数据,后台可以恢复。

  1. name 获取表名,定位到表
  2. 通过 id 定位到具体数据,更改属性值。

注意:

    @classmethod
    def update(cls, id, form):
        name = cls.__name__
        query = {
            '_id': ObjectId(id),
        }
        values = {
            '$set': form,
        }
        cls.db[name].update_one(query, values)

改:
  update() 方法类似于 delete() 方法

    @classmethod
    def all(cls, **kwargs):
        kwargs['deleted'] = False
        if 'id' in kwargs:
            kwargs['_id'] = ObjectId(kwargs['id'])
            kwargs.pop('id')
        name = cls.__name__
        docuemtns = cls.db[name].find(kwargs)
        l = [cls._new_with_bson(d) for d in docuemtns]
        return l

查(all):

  1. 加入没有被删除的限定条件
  2. 将外部传入的 id 改为 mongodb_id ,并删除 id字典也有 pop() 方法,返回删除的键的值,参数为键;
  3. 通过 mongodb 的 find() 方法,找到所有符合条件的数据,(列表)
  4. 实例以字典形式储存至 mongodb,以实例(属性)形式返回:
    @classmethod
       def _new_with_bson(cls, bson):
           """
           这是给内部 all 这种函数使用的函数
           从 mongo 数据中恢复一个 model
           """
           m = cls()
           for key in bson:
               setattr(m, key, bson[key])
           m.id = str(bson['_id'])
           return m
    
    @classmethod
    def one(cls, **kwargs):
        documents = cls.all(**kwargs)
        if len(documents) > 0:
            return documents[0]
        else:
            return None

查(one):
  返回所有符合条件的第一个数据;

    def json(self):
        d = self.__dict__
        d.pop('_id')
        return d

不知道这个函数有什么作用,感觉其他地方也没用到;

总结:

  1. 基类实现增删查改,方便子类调用;
  2. id_id 的转换
  3. 储存数据的格式与取出数据的格式
  4. 极度的条件抽象
  5. 初始化时间的创建节点
  6. mongodb 的各种方法
    save()、update_one()、find()、




数据库连接:

  1. 引入中间包
    from pymongo import MongoClient

  2. 在基类内建立类变量,连接数据库管理系统建立数据库文件
    db = MongoClient()['web21']

    • 实际是是两步:db = MongoClient('localhost', '27017')['web21']
  3. 建立集合保存
    _id = db[self.__class__.__name__].save(self.__dict__)

    • 也是两步,建表(获取集合)、保存
      classname = self.__class__.__name__
      _id = db[classname].save(classname.__dict__)

    一般封装在基类的 save() 方法中;
    插入方法:save()、insert_one()、insert_many([,])

    def save(self):
       name = self.__class__.__name__
       # print('save', self.__dict__)
       _id = self.db[name].save(self.__dict__)
       self.id = str(_id)
    

基类是数据库文件,子类就是表,实例的集合组成表,实例的属性就是字段

数据库术语.png 图片.png

https://www.cnblogs.com/Lin-Yi/p/7384991.html


上一篇 下一篇

猜你喜欢

热点阅读