class MixinUser(Model): leancloud.init(config.leancloud.APP_ID, config.leancloud.APP_KEY) mixin_id = Field() name = Field() avatar = Field() # created_at = Field(default=datetime.now()) @staticmethod def add(**kwargs): user = MixinUser.create(**kwargs) user.commit() @staticmethod def find(**kwargs): user = MixinUser.query().filter_by(**kwargs).first() return user @staticmethod def list(): return MixinUser.query().order_by(MixinUser.created_at.desc).find(limit=10) @staticmethod def delete(m): m.drop() # m = MixinUser.add(name='lee44c1', mixin_id='3553', avatar='dd324dddf') # l = MixinUser.list() # for mm in l: # print(mm.name, mm.created_at)
class RatingMap(Model): leancloud.init(config.leancloud.APP_ID, config.leancloud.APP_KEY) user_id = Field() robot = Field() score = Field() @staticmethod def rating(user_id, app_id, score): robot = Robots.find(app_id=app_id) robots = leancloud.Object.extend('Robots') rating_map = leancloud.Object.extend('RatingMap') ratingMap = rating_map() ratingMap.set('user_id', user_id) ratingMap.set('robot', robots.create_without_data(robot.object_id)) ratingMap.set('score', score) ratingMap.save() # caculate Robots score_avg,add rating_num r = Robots.find(app_id=app_id) print(r.rating_num, r.score_avg) rating_num = r.rating_num + 1 score_avg = (r.score_avg * r.rating_num + score) / rating_num Robots.update(r, rating_num=rating_num + 1, score_avg=score_avg) # RatingMap.rating(user_id='3553', app_id='7000', score=5)
class Person(models.Model): __lc_cls__ = self.cls_name name = Field()
class M(Base): field = Field()
class People(models.Model): __lc_cls__ = 'TEST_People' name = Field() age = Field() profile = Field()
class ModelA(models.Model): __lc_cls__ = self.cls_name name = Field() age = Field()
class ModelB(BaseA, BaseB): name = Field()
class BaseB(models.Model): name = Field()
class ModelA(models.Model): name = Field()
class BaseModelB(models.Model): age = Field()
class BaseModelA(models.Model): name = Field()
class Person(BaseModel): age = Field()
class Model(object, metaclass=ModelMeta): """ Model 基类,自定义的表模型应当继承于 Model。 继承的 Model 类声明方式类似于 SQLAlchemy 和 Django ORM。 例子: :: from leancloud_better_storage.storage.models import Model from leancloud_better_storage.storage.fields import StringField, NumberField class Person(Model): name = StringField(max_length=8) age = NumberField() 模型已经包含了三个由 LeanCloud 产生的字段: - `object_id` - `created_at` - `updated_at` 这三个字段会由 LeanCloud 自动填充,所以无需在调用`create`时传入。尤其是对于 `object_id`, 通常不应在创建时指定。 关于可以使用的字段类,请参考 :ref:`leancloud_better_storage.storage.fields`。 """ __lc_cls__ = '' __fields__ = {} object_id = Field('objectId', default=auto_fill) created_at = Field('createdAt', default=auto_fill) updated_at = Field('updatedAt', default=auto_fill) @classmethod def register_pre_create_hook(cls, fn): """ 注册新对象保存时的钩子函数。对于 object_id 为空的对象将被视为新对象。 """ cls._pre_create_hook.append(fn) @classmethod def register_pre_update_hook(cls, fn): """ 注册对象更新时的钩子函数。 """ cls._pre_update_hook.append(fn) @classmethod def register_pre_delete_hook(cls, fn): """ 注册删除对象时调用的钩子函数。 """ cls._pre_delete_hook.append(fn) def _do_life_cycle_hook(self, life_cycle): hook_fn_attr_name = '_{}_hook'.format(life_cycle) hook_fn = getattr(self, hook_fn_attr_name, []) for cls in self.__class__.mro(): hook_fn.extend(getattr(cls, hook_fn_attr_name, [])) for fn in hook_fn: fn(self) @property def lc_object(self): return self._lc_obj def __init__(self, lc_obj=None): self._lc_obj = lc_obj @classmethod def create(cls, **kwargs): """ 创建一个 Model 实例。这个实例不会立即保存至 LeanCloud。 你可以通过关键字参数来初始化实例字段。 看下面的例子: :: from leancloud_better_storage.storage.models import Model from leancloud_better_storage.storage.fields import StringField, NumberField class Person(Model): name = StringField(nullable=False) age = NumberField() remilia = Person.create(name='remilia scarlet', age=549) # just a random age number, ignore it. flandre = Person.create(name='flandre scarlet', age=549) 被指定 `nullable` 为 `False` 并且 `default` 为 `None` 、 `undefined` 的字段必须在初始化时提供,否则将会产生一个 `KeyError` 。 需要注意的是 `default` 被指定为 `None` 时的行为和 `undefined` 行为不同,因为在传输和存储的过程, 序列化为JSON/BSON的Python的 `None` 会被认作 `null` ,而 `undefined` 则令字段不出现。 这一概念与 JavaScript 近乎一致。 :param kwargs: 初始化字段 :return: """ # check does given keyword arguments matches model schema input_keys = set(kwargs.keys()) required_keys = set(cls.__meta__.required_fields.keys()) all_keys = set(cls.__meta__.fields.keys()) if not input_keys.issubset(all_keys): raise KeyError("Unknown field name {}".format(input_keys - all_keys)) elif not required_keys.issubset(input_keys): raise KeyError("Missing required field {}".format(required_keys - input_keys)) # fill fields and DO NOT BREAK field restriction lc_obj = leancloud.Object.create(cls.__lc_cls__) obj = cls(lc_obj) for attr_name, value in dict(cls.__meta__.attributes_default, **kwargs).items(): setattr(obj, attr_name, value() if callable(value) else value) return obj def commit(self, where=None, fetch_when_save=None): """ 保存这个对象到 LeanCloud。 使用 LeanCloud SDK 的 `save` 实现。 会触发 `pre_create` 回调。 :return: self """ if where: if not isinstance(where, (leancloud.Query, Query)): raise ValueError( 'Param `where` should be instance of storage.query.Query or leancloud.Query.' ) if isinstance(where, Query): where = where.leancloud_query self._do_life_cycle_hook( 'pre_create' if self.object_id is None else 'pre_update') self._lc_obj.save(where, fetch_when_save) return self @classmethod def commit_all(cls, *models): """ 保存多个对象到 LeanCloud。所有传入的对象必须是同一个 Model 类的实例。 使用 LeanCloud SDK 的 `save_all` 实现。 保存会触发 `pre_create` 回调。 :param models: :return: """ for instance in models: instance._do_life_cycle_hook( 'pre_create' if instance.object_id is None else 'pre_update') leancloud.Object.extend(cls.__lc_cls__).save_all( [instance._lc_obj for instance in models]) def drop(self): """ 从 LeanCloud 删除这个对象。 删除后对象进入不可用状态,请不要再做任何读写操作。 :return: None """ self._do_life_cycle_hook('pre_delete') self._lc_obj.destroy() self._lc_obj = None @classmethod def drop_all(cls, *models): """ 从 LeanCloud 删除多个对象,所有传入的对象必须是同一个 Model 的实例。 删除使用 LeanCloud SDK 提供的 `destroy_all` 实现。 删除会触发在 Model 类注册的 `pre_delete` 回调。 :param models: 一个或多个 Model 类实例 :return: None """ for instance in models: instance._do_life_cycle_hook('pre_delete') leancloud.Object.extend(cls.__lc_cls__).destroy_all( [instance._lc_obj for instance in models]) for model in models: model._lc_obj = None @classmethod def query(cls): return Query(cls)
class Model(object, metaclass=ModelMeta): __lc_cls__ = '' __fields__ = {} __data__ = None object_id = Field('objectId') created_at = Field('createdAt') updated_at = Field('updatedAt') @property def lc_object(self): return self._lc_obj def __init__(self, lc_obj=None): self._lc_obj = lc_obj self.__data__ = {} def __getattribute__(self, item): ret = super(Model, self).__getattribute__(item) if isinstance(ret, Field): field_name = self._get_real_field_name(item) if field_name not in self.__data__: result = self._lc_obj.get(field_name) if result is None: return ret.default self.__data__[field_name] = ret.to_python_value(result) return self.__data__[field_name] return ret def __setattr__(self, key, value): field = self.__fields__.get(key) if field: if isinstance(value, operation.BaseOp): if field.field_name in self.__data__: del self.__data__[field.field_name] self._lc_obj.set(field.field_name, value) else: self.__data__[field.field_name] = value self._lc_obj.set(field.field_name, field.to_leancloud_value(value)) else: return super(Model, self).__setattr__(key, value) @classmethod def _get_real_field_name(cls, name): if name in cls.__fields__: return cls.__fields__[name].field_name return None @classmethod def create(cls, **kwargs): if not {*kwargs.keys()}.issubset({*cls.__fields__.keys()}): raise KeyError( 'Unknown field name {0}'.format({*kwargs.keys()} - {*cls.__fields__.keys()})) attr = { field.field_name: field.default() if callable(field.default) else field.default for field in filter(lambda v: v.default is not undefined, cls.__fields__.values()) if field.nullable or field.default } for key, val in kwargs.items(): real_name = cls._get_real_field_name(key) attr[real_name] = val missing_fields = { key for key, field in cls.__fields__.items() if field.nullable is False and field.default in ( None, undefined) and field.field_name not in attr } if len(missing_fields) != 0: raise KeyError( 'Missing required field {0}.'.format(missing_fields)) data = { k: cls.__fields__[k].to_leancloud_value(v) for (k, v) in attr.items() } lc_obj = leancloud.Object.create(cls.__lc_cls__, **data) return cls(lc_obj) def commit(self, **kwargs): self._lc_obj.save(**kwargs) self.__data__ = {} return self @classmethod def commit_all(cls, *models): leancloud.Object.extend(cls.__lc_cls__).save_all( [model._lc_obj for model in models]) def drop(self): self._lc_obj.destroy() self._lc_obj = None @classmethod def drop_all(cls, *models): leancloud.Object.extend(cls.__lc_cls__).destroy_all( [model._lc_obj for model in models]) for model in models: model._lc_obj = None @classmethod def query(cls): return Query(cls) @classmethod def create_without_data(cls, object_id): return cls( leancloud.Object.extend( cls.__lc_cls__).create_without_data(object_id)) @classmethod def createPointer(cls, object_id): return Pointer(cls.__lc_cls__, object_id) def toPointer(self): return Pointer(self.__lc_cls__, self.object_id)
class Robots(Model): leancloud.init(config.leancloud.APP_ID, config.leancloud.APP_KEY) name = Field() desc = Field(default='') tags = Field(default='') app_id = Field() app_code = Field() author = Field() wechat = Field() email = Field() verified = Field(default=False) score_avg = Field(default=0) rating_num = Field(default=0) search_num = Field(default=0) publish_at = Field(default=datetime.now()) @staticmethod def add(**kwargs): robot = Robots.create(**kwargs) robot.commit() @staticmethod def find(**kwargs): robot = Robots.query().filter_by(**kwargs).first() return robot @staticmethod def search(keyword): robots = leancloud.Object.extend('Robots') query_name = robots.query.contains('name', keyword) query_tags = robots.query.contains('tags', keyword) query_desc = robots.query.contains('desc', keyword) return leancloud.Query.or_(query_name, query_tags, query_desc).limit(10).find() @staticmethod def hot(): return Robots.query().order_by(Robots.search_num.desc).find(limit=10) @staticmethod def new(): return Robots.query().order_by(Robots.created_at.desc).find(limit=10) @staticmethod def top(): return Robots.query().order_by(Robots.score_avg.desc).find(limit=10) @staticmethod def update(target_robot, **kwargs): for k, v in kwargs.items(): setattr(target_robot, k, v) target_robot.commit() @staticmethod def searched(target_robot): search_num = target_robot.search_num Robots.update(target_robot, search_num=search_num + 1) @staticmethod def delete(r): r.drop() # robot_str_tmp = '\n\nName:{name}\nCode:{app_code}\nTags:{tags}\nDescription:{desc}' # reply_robot_code = '\nReply {Code} will send you Robot Contact Card' # # realData = '乌云' # s_list = Robots.search(keyword=realData) # # reply_str = 'Mixin Robots Search Results : ' + realData # # # for r in s_list: # reply_str += robot_str_tmp.format(name=r.get('name'), app_code=r.get('app_code'), # tags=r.get('tags'), desc=r.get('desc')) # # print(reply_str)
class Person(models.Model): __lc_cls__ = self.cls_name name = Field(nullable=False, default='Hi')
class MixinSession(Model): leancloud.init(config.leancloud.APP_ID, config.leancloud.APP_KEY) user_id = Field() action_in = Field() app_id = Field() created_timestamp = Field(default=datetime.now().timestamp()) @staticmethod def add(**kwargs): session = MixinSession.create(**kwargs) session.commit() @staticmethod def find(**kwargs): session = MixinSession.query().order_by( MixinSession.created_at.desc).filter_by(**kwargs).first() return session @staticmethod def get_app_id(user_id, action_in): r = MixinSession.find(user_id=user_id, action_in=action_in) if r: return r.app_id else: return False @staticmethod def inAction(user_id, action_in, **kwargs): s = MixinSession.find(user_id=user_id) if s is not None: if s.action_in != action_in: MixinSession.delete(s) MixinSession.add(user_id=user_id, action_in=action_in, created_timestamp=datetime.now().timestamp(), **kwargs) print(user_id + ' add action_in ' + action_in) else: s.created_timestamp = datetime.now().timestamp() s.commit() print(user_id + ' update action_in ' + action_in) else: MixinSession.add(user_id=user_id, action_in=action_in, created_timestamp=datetime.now().timestamp(), **kwargs) print(user_id + ' add action_in ' + action_in) @staticmethod def isInAction(user_id, action_in): s = MixinSession.find(user_id=user_id) if s is not None: if s.action_in != action_in: # MixinSession.delete(s) return False else: delta_time = datetime.now().timestamp() - s.created_timestamp print(delta_time) if delta_time < WAIT_TO_ACTION: print(action_in + ' is in action') return True else: print('wait to long') return False else: return False @staticmethod def delete(m): m.drop() # # MixinSession.inAction(user_id='d33f7efd-4b0b-41ff-baa3-b22ea40eb44f', action_in='search') # # s = MixinSession.find(user_id='d33f7efd-4b0b-41ff-baa3-b22ea40eb44f') # print(s) # # ina = MixinSession.isInAction(user_id='d33f7efd-4b0b-41ff-baa3-b22ea40eb44f', action_in='search') # print(ina) # if MixinSession.isInAction(user_id='d33f7efd-4b0b-41ff-baa3-b22ea40eb44f', action_in='search'): # print('type:' + 'kkk') # user_id = 'd33f7efd-4b0b-41ff-baa3-b22ea40eb44f' # MixinSession.inAction(user_id=userId, action_in='search') # MixinSession.inAction(user_id=userId, action_in='app_code') # MixinSession.add(user_id=user_id, action_in='rate_score', created_timestamp=datetime.now().timestamp(), app_id='dfdf')
class PersonB(BaseModelA, BaseModelB): bio = Field()
class ModelB(BaseModel): age = Field()
class Person(models.Model): name = Field()
class ModelA(BaseA): name = Field()
class Person(Model): name = Field() age = Field() gender = Field() sweet_heart = RefField(ref_cls='Person')
class ModelC(BaseA, BaseB): age = Field()
class PersonB(models.Model): __lc_cls__ = self.cls_name name = Field('NameField')
class BaseModel(models.Model): __lc_cls__ = self.cls_name name = Field()
class PersonA(BaseModel): __lc_cls__ = self.cls_names[1] age = Field()
class PeopleProfile(models.Model): __lc_cls__ = 'TEST_PeopleProfile' score = Field()
class M(Model): field = Field()