【问题标题】:Flask-SQLAlchemy validation: prevent adding to relationship based on other fieldFlask-SQLAlchemy 验证:防止添加基于其他字段的关系
【发布时间】:2021-07-13 16:21:21
【问题描述】:

我正在使用 flask-sqlalchemy 并尝试验证对我的数据库的输入。对于单个字段,验证装饰器效果很好。但是,我在阻止值被添加到基于另一个字段的值的集合/关系中时遇到问题。例如,考虑以下数据模型:

class MyRelation(db.Model):
    __tablename__ = "my_relation"
    id = db.Column(db.Integer, primary_key=True)
    my_data_id = db.Column(db.Integer, db.ForeignKey("my_data.id"))
    some_value = db.Column(db.String)

class MyData(db.Model):
    __tablename__ = "my_data"
    id = db.Column(db.Integer, primary_key=True)
    some_relation = db.relationship("MyRelation", backref="my_data")
    some_other_value = db.Column(db.Boolean)

我遇到的问题是,如果some_other_value == True,我想确保some_relation 为空。我研究了以下选项。我不确定是否可以调整其中任何一个以提供预期的功能:

  1. @validates 与多个字段一起使用为specified here。这种方法的问题是它似乎一个一个地验证集合,并且在验证中返回 None 以对格式不正确的输入产生 sqlalchemy.orm.exc.FlushError: Can't flush None value found in collection Job.alternate_attributes。返回一个空列表也不起作用。
  2. 使用before_insert 事件侦听器,如outlined here。我看到的挑战是,这似乎与official docs 中的关系事件不兼容。
  3. 使用before_flush 事件监听器,听起来它可能与这个用例兼容,但老实说,鉴于我的目标,我很难找到一个很好的例子来说明如何使用它。它非常抽象,我在文档中看不到任何示例(examples 中的bothbefore_flush section 末尾提到实际上不包含对before_flush 方法的任何引用,它们应该是演示)。

任何指导将不胜感激 - 谢谢!

【问题讨论】:

    标签: python sqlalchemy flask-sqlalchemy


    【解决方案1】:

    回答我自己的问题 - before_flush 事件监听器是这里的方法:

    @db.event.listens_for(db.session, 'before_flush')
    def validate_and_modify_relationships(session, flush_context, instances):
        """
        Complex validation that cannot be performed with @valdiates
        """
        
        # new records only (for updates only, use session.dirty)
        for instance in session.new:
            if isinstance(instance, MyData):
                if instance.some_other_value:
                    instance.some_relation = []
    

    按预期工作,我唯一不介意的是它是否可以是 MyData 类中的一个方法以及我的其他 @validates 方法,但否则这很清楚。

    【讨论】:

      猜你喜欢
      • 2018-01-12
      • 1970-01-01
      • 1970-01-01
      • 2017-09-08
      • 2023-03-10
      • 2015-07-24
      • 2016-01-02
      • 2021-07-11
      • 1970-01-01
      相关资源
      最近更新 更多