kol*_*pto 9 python sql postgresql triggers alembic
假设数据库中有一些带有函数的触发器,如下所示:
-- Insert a new entry into another table
-- every time a NEW row is inserted
CREATE FUNCTION trgfunc_write_log() RETURNS TRIGGER AS $$
BEGIN
INSERT INTO some_other_table (
-- some columns
meter_id,
date_taken,
temperature,
) values (
NEW.meter_id,
NEW.time_taken,
NEW.temperature
);
return NEW;
END;
$$ language 'plpgsql';
-- The trigger itself: AFTER INSERT
CREATE TRIGGER trg_temperature_readings
AFTER INSERT ON temperature_readings
FOR EACH ROW
EXECUTE FUNCTION trgfunc_write_log();
Run Code Online (Sandbox Code Playgroud)
通常,此触发器将位于我的 SqlAlchemy 模型旁边,并使用如下内容自动创建:
from sqlalchemy import DDL, event
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Reading(Base):
...
create_trigger = DDL(""" ...SQL... """)
event.listen(Reading.__table__, 'after_create', create_trigger)
Run Code Online (Sandbox Code Playgroud)
通过 Alembic 迁移对此类触发器及其功能进行版本控制的最佳实践是什么?
bra*_*142 10
我最近在应用程序中遇到了同样的问题,并在 Alembic Cookbook 中找到了这篇文章。
它概述了创建一个对象的有点复杂的策略,该对象封装了用于在其他对象中创建视图、存储过程或触发器的名称和 SQL,这些对象用于执行 Alembic 操作以升级和降级该架构对象。在 Alembic 版本中使用时,它看起来像这样:
from alembic import op
from my_module import ReplaceableObject
my_trigger = ReplaceableObject(
"trigger_name",
"""...SQL..."""
)
def upgrade():
op.create_trigger(my_trigger)
def downgrade():
op.drop_trigger(my_trigger)
Run Code Online (Sandbox Code Playgroud)
我的团队目前正在讨论与视图或存储过程相比,这个策略对于简单的触发器来说是否过于复杂。您可以更频繁地更新这些架构对象,从而使 Cookbook 抽象中概述的大部分行为比简单的触发器更有价值。
另一个建议的选择是这样的:
from alembic import op
create_trigger = """...SQL..."""
drop_trigger = """...SQL..."""
def upgrade():
op.execute(create_trigger)
def downgrade():
op.execute(drop_trigger)
Run Code Online (Sandbox Code Playgroud)
这两个实现看起来几乎相同,这就是 Cookbook 抽象对于简单触发器来说不必要复杂的论点。
归档时间: |
|
查看次数: |
4984 次 |
最近记录: |