3

我有以下内容:

模型.py

class Policy(db.Model):
    policy_id = db.Column(db.Integer, primary_key=True)
    client_reference = db.Column(db.String(50), nullable=False)
    submission_id = db.Column(db.ForeignKey('submission.submission_id'), nullable=False)

    submission = relationship("Submission", back_populates="policies", lazy='joined')


class Submission(db.Model):
    submission_id = db.Column(db.Integer, primary_key=True)
    client_reference = db.Column(db.String(50), nullable=False)

    policies = db.relationship('Policy', back_populates='submission', lazy='joined')

架构.py

class PolicySchema(SQLAlchemyAutoSchema):
    class Meta:
        model = Policy
        include_relationships = True
        load_instance = True
        unknown = INCLUDE
        exclude = ("submission",)

    submission_id = auto_field("submission")


class SubmissionSchema(SQLAlchemyAutoSchema):
    class Meta:
        model = Submission
        include_relationships = False
        load_instance = True

    policies = fields.Nested(PolicySchema, many=True, allow_none=True)

路线.py

@submission_api.route('/submission/', methods=['POST'])
def add_new():
    body = request.get_json()
    validated_request = SubmissionSchema().load(body, session=db.session)
    db.session.add(validated_request)
    db.session.commit()
    return jsonify({"submission_id": validated_request.submission_id}), 200

如果我尝试使用以下方法将新记录添加到提交中:

{
    "client_reference": "POL1",
    "description": "hello"
}

它工作正常。

如果我打电话给:

{
    "client_reference": "POL1","description": "hello",
    "policies": [{"client_reference": "A1"}]
}

我收到此错误:

File "/usr/local/lib/python3.8/site-packages/marshmallow_sqlalchemy/schema/load_instance_mixin.py", line 89, in load
    raise ValueError("Deserialization requires a session")
ValueError: Deserialization requires a session

我不知道为什么。我以相同的方式为两者传递会话(它的功能相同)。我进行了更改以导致此问题,因为它正在工作(提醒更频繁地提交代码)。

4

1 回答 1

2

恐怕没有真正的解决方案,只有这个github issue中讨论的解决方法。引用TMiguelIT 的话

我们创建自己的继承自原始 Marshmallow Nested 的 Nested 字段,允许我们向下传递会话对象是否不合理?这会以任何方式降低可用性吗?

据我了解,解决方案应如下所示:

from marshmallow import fields

class Nested(fields.Nested):
    """Nested field that inherits the session from its parent."""

    def _deserialize(self, *args, **kwargs):
        if hasattr(self.schema, "session"):
            self.schema.session = db.session  # overwrite session here
            self.schema.transient = self.root.transient
        return super()._deserialize(*args, **kwargs)

因此,您在会话顶部创建自己的Nested字段(我刚刚从 marshmallow-sqlalchemy 复制了代码)schemy.py并覆盖会话。

于 2020-08-05T17:23:18.060 回答