python – 使用Marshmallow模式过滤sqlalchemy表更新

python – 使用Marshmallow模式过滤sqlalchemy表更新,第1张

概述我正在Flask中开发api,使用Marshmallow进行序列化/反序列化/验证,使用SQLAlchemy作为我的ORM. 在我的更新功能中,我想限制可以更新的字段,例如我不希望用户此刻能够更改他们的电子邮件. 为了实现这一点,我设置了一个模式(UserSchema),其字段受元组(UserSchemaTypes.UPDATE_FIELDS)限制.元组不包含电子邮件. 我遇到的问题是电子邮件是我 我正在Flask中开发API,使用Marshmallow进行序列化/反序列化/验证,使用sqlAlchemy作为我的ORM.

在我的更新功能中,我想限制可以更新的字段,例如我不希望用户此刻能够更改他们的电子邮件.

为了实现这一点,我设置了一个模式(UserSchema),其字段受元组(UserSchemaTypes.UPDATE_FIELDS)限制.元组不包含电子邮件.

我遇到的问题是电子邮件是我的数据库中用户行的必填字段.

因此,当我使用模式(users_schema.load(user_Json))创建User模型对象时,会向sqlalchemy会话添加非法对象.

#schema to valIDate the posted fIElds against  users_schema = UserSchema(only=UserSchemaTypes.UPDATE_FIELDS)#attempt to deserialize the posted Json to a User model object using the schemauser_data = users_schema.load(user_Json)if not user_data.errors:#update data passed valIDation   user_update_obj = user_data.data    User.update(user_ID,vars(user_update_obj))

在我的更新函数本身,然后我必须通过db.session.expunge_all()从会话中删除这个非法对象,就好像我没有收到OperationalError.

@staticmethod    def update(p_ID,data):    db.session.expunge_all()#Hack I want to remove    user = User.query.get(p_ID)    for k,v in data.iteritems():        setattr(user,k,v)    db.session.commit()

删除db.session.expunge_all()时收到的OperationalError:

OperationalError: (raised as a result of query-invoked autoflush; consIDer        using a session.no_autoflush block if this flush is occurring prematurely) (_MysqL_exceptions.OperationalError) (1048,"Column 'email' cannot be   null") [sql: u'INSERT INTO user (email,password,active,phone,current_login_at,last_login_at,current_login_ip,last_login_ip,login_count) VALUES (%s,%s,%s)'] [parameters: (None,None,1,'0444',None)]

这样做有更好/更清洁的方法吗?

解决方法 来自Steven Loria https://github.com/marshmallow-code/marshmallow-sqlalchemy/issues/33#issuecomment-147008000

您可以采取以下几种不同的方法:

选项1:字段参数

from marshmallow import Schema,fIElds,pre_loadclass BaseSchema(Schema):    @pre_load    def check_update_fIElds(self,data)        non_update_fIElds = set([            fname,fobj for fname,obj in self.fIElds            if fobj.Metadata.get('can_update') is False        ])        return {            key: value for key,value in data.items()            if key not in non_update_fIElds        }class UserSchema(BaseSchema):    name = fIElds.str()    email = fIElds.Str(can_update=False)

选项2:类Meta选项

from marshmallow import Schema,SchemaOpts,pre_loadclass BaseSchemaOpts(SchemaOpts):    def __init__(self,Meta):        super().__init__(Meta)        self.update_fIElds = getattr(Meta,'update_fIElds',set())class BaseSchema(Schema):    OPTIONS_CLASS = BaseSchemaOpts    email = fIElds.Str(can_update=False)    @pre_load    def check_update_fIElds(self,data)        non_update_fIElds = set(self.fIElds) - set(self.opts.update_fIElds)        return {            key: value for key,value in data.items()            if key not in non_update_fIElds        }class UserSchema(BaseSchema):    name = fIElds.str()    email = fIElds.str()    class Meta:        update_fIElds = ('name',)
总结

以上是内存溢出为你收集整理的python – 使用Marshmallow模式过滤sqlalchemy表更新全部内容,希望文章能够帮你解决python – 使用Marshmallow模式过滤sqlalchemy表更新所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1197410.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存