如何解决处理 Marshmallow 改变 SQLAlchemy 对象的优雅方式
我发现自己处于一种似乎没有优雅解决方案的情况。考虑以下(伪类)REST API 代码
bp = Blueprint('Something',__name__,url_prefix='/api')
class SomeOutputSchema(ma.SQLAlchemyAutoSchema)
class Meta:
model = MyModel
@pre_dump(pass_many=False)
def resolveFilePath(self,ormObject,many):
# ormObject has a parent via a relationship
ormObject.filePath = os.path.join(ormObject.parent.rootDir,ormObject.filePath)
@bp.route("/someRoute")
class SomeClass(MethodView):
def put(self):
ormObject = MyModel(filePath = "/some/relative/path")
db.session.add(ormObject)
db.session.flush()
outputDump = SomeOutputSchema().dump(ormObject)
# Lots of other code that uses outputDump...
# Only commit here in case
# anything goes wrong above
db.session.commit()
return jsonify({"data": outputDump}),201
我有
- 一个 PUT 端点,它将创建一个新资源,然后返回该资源的转储。
- 一个具有 filePath 属性的 ORM 对象。这必须存储为相对路径。
- 棉花糖模式。它有一个@pre_dump 方法通过使用另一个属性(
parent.rootDir
)来解析文件路径
所以基本上流程是
- 创建新资源
- 创建要使用的该资源的架构转储
- 提交
- 返回模式转储
所以最后,问题是:outputDump
的{{1}}实际上改变了@pre_dump
,所以它现在是一个完全解析的路径{ {1}} 被调用。我的第一个直觉是创建一个 ormObject
的深层副本,但失败了
db.session.commit()
并不是说这件事很难解决,而是以我目前的知识,似乎很难优雅地解决。我需要相对于数据库的路径,否则解决。
我目前的解决方案是告诉 ormObject
在这种情况下跳过 "Parent instance <MyModel at 0x7f31cdd44240> is not bound to a Session; lazy load operation of attribute 'parent' cannot proceed (Background on this error at: http://sqlalche.me/e/14/bhk3)"
,然后取 SomeOutputSchema
,然后在架构转储之后解析文件路径。但这对我来说真的很恶心。
我很想听听关于这方面的任何想法,因为目前我的代码感觉很混乱,我不喜欢只是离开它并继续推进的想法。
解决方法
通过使用 @post_dump
并使用 pass_original=True
访问原始对象解决
class SomeOutputSchema(ma.SQLAlchemyAutoSchema)
class Meta:
model = MyModel
@post_dump(pass_original=True)
def resolveFilePath(self,data,ormObject,many):
data['filePath'] = os.path.join(ormObject.parent.rootDir,ormObject.filePath)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。