python - 在 sqlalchemy 中触发

标签 python triggers sqlalchemy

我有两个通过外键关联的表,这里他们使用的是声明式映射

class Task(DeclarativeBase):
    __tablename__ = 'task'
    id = Column(Integer, primary_key=True)
    state = Column(Integer, default=0)
    obs_id = Column(Integer, ForeignKey('obs.id'), nullable=False)

class Obs(DeclarativeBase):
    __tablename__ = 'obs'
    id = Column(Integer, primary_key=True)
    state = Column(Integer, default=0)

因此,我想在 obs.state 更改为值 2 时更新相关的 task.state。目前我正在手动执行(使用称为任务的关系)

obs.state = 2
obs.task.state = 2

但我更喜欢使用触发器来完成它。我已经检查过这在 sqlite 中有效

CREATE TRIGGER update_task_state UPDATE OF state ON obs
  BEGIN
    UPDATE task SET state = 2 WHERE (obs_id = old.id) and (new.state = 2);
  END;

但我找不到如何在 sqlalchemy 中表达它。我读过insert update defaults好几次了,还是找不到路。我什至不知道这是否可能。

最佳答案

您可以使用 DDL class 在数据库中创建触发器:

update_task_state = DDL('''\
CREATE TRIGGER update_task_state UPDATE OF state ON obs
  BEGIN
    UPDATE task SET state = 2 WHERE (obs_id = old.id) and (new.state = 2);
  END;''')
event.listen(Obs.__table__, 'after_create', update_task_state)

这是最可靠的方法:当不使用 ORM 时,它适用于批量更新,甚至适用于应用程序外部的更新。但是也有缺点:

  • 您必须确保您的触发器存在并且是最新的;
  • 它不可移植,所以如果你改变数据库,你必须重写它;
  • SQLAlchemy 不会更改已加载对象的新状态,除非您使它过期(例如,使用某些事件处理程序)。

下面是一个不太可靠的(它只在 ORM 级别进行更改时有效),但更简单的解决方案:

from sqlalchemy.orm import validates

class Obs(DeclarativeBase):
    __tablename__ = 'obs'
    id = Column(Integer, primary_key=True)
    state = Column(Integer, default=0)
    @validates('state')
    def update_state(self, key, value):
        self.task.state = value
        return value

我的两个例子都以一种方式工作,即它们在 obs 发生变化时更新任务,但在任务更新时不触及 obs。您必须再添加一个触发器或事件处理程序以支持双向更改传播。

关于python - 在 sqlalchemy 中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7888846/

相关文章:

python - flask abort() 里面的 try block 行为

python - Celery 任务方法没有被调用

sql-server-2008 - SQL 更新触发器错误 -(无法创建触发器,因为表具有带有更新级联的外键)

javascript - zepto 触发器不工作

python - 当我希望通过升级内的 Session 对象更改数据时,如何测试 alembic 迁移?

python - 当矩阵中的行多 10 倍时,为什么 np.dot 不会(至少)长 10 倍

mysql - 基本 SQL 触发器

sqlalchemy - 检查对象是否是 sqlalchemy 模型实例

python - 在 SQLAlchemy 基类中定义抽象方法

python - 将Python输入转化为命令