我有以下SQLAlchemy模型:
PENDING_STATE = 'pending'
COMPLETE_STATE = 'success'
ERROR_STATE = 'error'
class Assessment(db.Model):
__tablename__ = 'assessments'
id = db.Column(db.Integer, primary_key=True)
state = db.Column(
db.Enum(PENDING_STATE, COMPLETE_STATE, ERROR_STATE,
name='assessment_state'),
default=PENDING_STATE,
nullable=False,
index=True)
test_results = db.relationship("TestResult")
class TestResult(db.Model):
__tablename__ = 'test_results'
name = db.Column(db.String, primary_key=True)
state = db.Column(
db.Enum(PENDING_STATE, COMPLETE_STATE, ERROR_STATE,
name='test_result_state_state'),
default=PENDING_STATE,
nullable=False,
index=True)
assessment_id = db.Column(
db.Integer,
db.ForeignKey(
'assessments.id', onupdate='CASCADE', ondelete='CASCADE'),
primary_key=True)
我正在尝试实现逻辑,以便在其任何测试结果处于错误状态时将评估更新为错误状态,并在所有测试结果都处于成功状态时将评估更新为成功状态。 / p>
我可以像这样编写原始SQL:
SELECT 'error'
FROM assessments
WHERE assessments.state = 'error' OR 'error' IN (
SELECT test_results.state
FROM test_results
WHERE test_results.assessment_id = 1);
但我不知道如何将其翻译成SQLAlchemy。我认为子查询会是这样的:
(select([test_results.state]).where(test_results.assessment_id == 1)).in_('error')
但是我无法找到任何方法来将查询结果与我在原始SQL中执行的文字进行比较。我发誓我必须遗漏一些东西,但我只是没有找到一种方法来编写返回布尔表达式的查询,我认为这基本上是我所反对的。只是简单的事情:
SELECT 'a' = 'b'
似乎没有出现在文档中。
有关如何在SQLAlchemy中表达此状态的任何想法?如果我看起来像是以愚蠢的方式解决这个问题,我也完全愿意重新思考我的架构。
谢谢!
答案 0 :(得分:0)
下面的查询应该进行error
检查。请记住,如果不是错误,则不会返回任何行。
q = (db.session.query(literal_column("'error'"))
.select_from(Assessment)
.filter(Assessment.id == sid)
.filter(or_(
Assessment.state == ERROR_STATE,
Assessment.test_results.any(TestResult.state == ERROR_STATE),
)))
如果您希望对success
进行类似的检查,您可以找到是否有TestResult
不 a success
并取消布尔结果。
答案 1 :(得分:0)
我实际上最终使用postgres触发器执行此操作,这可能是处理状态更新的更好方法。因此,对于错误案例,我得到了:
sqlalchemy.event.listen(TestResult.__table__, 'after_create', sqlalchemy.DDL("""
CREATE OR REPLACE FUNCTION set_assessment_failure() RETURNS trigger AS $$
BEGIN
UPDATE assessments
SET state='error'
WHERE id=NEW.assessment_id;
RETURN NEW;
END;
$$ LANGUAGE 'plpgsql';
CREATE TRIGGER assessment_failure
AFTER INSERT OR UPDATE OF state ON test_results
FOR EACH ROW
WHEN (NEW.state = 'error')
EXECUTE PROCEDURE set_assessment_failure();"""))
类似的成功'我计算测试结果数量与成功测试结果数量的情况。
尽管如此,我仍然可以通过van来回答我的问题!谢谢,我之前没有遇到任何关系。