Consider the following using sqlalchemy
:
from sqlalchemy.orm import validates
class DeviceTestResult:
__tablename__ = "device_test"
passed: bool = mapped_column(default=False, init=False)
failure_modes: Mapped[list['FailureMode']] = relationship(default_factory=list, back_populates='test')
@validates('failure_modes')
def validate_failure_modes(self, key, failure_mode):
"""
Validator for failure modes. When attribute is changed, updates passed to be false if there are any fails.
"""
currently_passes = all([fm.passed for fm in self.failure_modes])
self.passed = all([fm for fm in [currently_passes, failure_mode.passed]])
return failure_mode
class FailureMode:
__tablename__ = "failure_mode"
passed: bool = mapped_column()
test: Mapped['DeviceTestResult'] = relationship(back_populates='failure_modes', default=None)
completed_at: datetime = mapped_column(insert_default=datetime.now(), default=datetime.now())
@validates('passed')
def validate_test(self, key, passed):
"""
validator for passed. Updates associated test object status
"""
if self.test:
currently_passes = all([fm.passed for fm in self.test.failure_modes])
self.test._passed = all([fm for fm in [currently_passes, passed]])
return passed
# Case 1 - append, emits validate_failure_modes
device_test = DeviceTest()
failure_mode = FailureMode()
device.failure_modes.append(failure_mode)
# Case 2 - assignment, does not emit validate_failure_modes
device.failure_modes = [failure_mode]
validate_failure_modes
is emitted in case 1, but not in case 2.
How can I get validation in case 2? If that’s not possible, how can I restrict a user from setting the attribute using assignment, so that they can only modify via appending?
I’ve experimented with using sqlalchemy
descriptors & hybrids but haven’t gotten it to work.
New contributor
frimann is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.