def update_by_ma(self, schema, instance, commit=True): """根据marshmallow以及SQLa实例更新 :param schema: Schema Schema类或实例 :param instance: object Model对象 :param commit: bool 是否commit 此方法用以更新Sqla实例的字段,基于一个marshmallow类或实例, 根据marshmallow类的load字段加载。由于需要一个临时变量的 instance,对于需要同时处理复杂relationship的子关系需要增 加指定active_history=True来跟踪变化以维持正确的加载。 形如: >>> class Remote(Model): id = Column(Integer(), primary_key=True) name = Column(String(80)) >>> class Local(Model): id = Column(Integer(), primary_key=True) remote_id = Column(Integer()) remote = relationship("Remote", active_history=True, backref=backref('local', active_history=True) ) 在这里需要修改Remote中name以及关系时。 """ from sqlalchemy.orm.attributes import ( get_attribute, del_attribute, set_attribute, ) from marshmallow import Schema if not isinstance(schema, Schema): schema = schema() db.session.add(instance) loadable_fields = [ k for k, v in schema.fields.items() if not v.dump_only ] with db.session.no_autoflush: for field in loadable_fields: set_attribute(self, field, get_attribute(instance, field)) del_attribute(instance, field) db.session.expunge(instance) self.save(commit)
def __delattr__(self, key): if is_instrumented(self, key): del_attribute(self, key) else: del self._goofy_dict[key]
def __delattr__(self, key): if is_instrumented(self, key): del_attribute(self, key) else: del self._goofy_dict[key]
def _setattr_from_instance(self, fields: List[str], instance: db.Model): with db.session.no_autoflush: for field in fields: set_attribute(self, field, get_attribute(instance, field)) del_attribute(instance, field)
def _setattr_from_instance(self, fields: List[str], instance: _M) -> None: with self.session().no_autoflush: for field in fields: set_attribute(self.instance(), field, get_attribute(instance, field)) del_attribute(instance, field)