在我的更新功能中,我想限制可以更新的字段,例如我不希望用户此刻能够更改他们的电子邮件.
为了实现这一点,我设置了一个模式(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表更新所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)