向SQLAlchemy基类添加触发器

2024-04-26 19:01:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在为一个新的Postgres数据库创建一个SQLAlchemy基类,并希望将簿记字段合并到其中。具体地说,我想要自动更新modified_atmodified_by的两个列。我能够找到如何对单个表执行此操作,但将这部分作为基类的一部分似乎更为棘手。在

我的第一个想法是尝试利用declared_attr功能,但实际上我不想让触发器成为模型中的一个属性,这样看起来就不正确了。然后我看了使用event.listen添加触发器:

trigger = """
CREATE TRIGGER update_{table_name}_modified
BEFORE UPDATE ON {table_name}
FOR EACH ROW EXECUTE PROCEDURE update_modified_columns()
"""

def create_modified_trigger(target, connection, **kwargs):
    if hasattr(target, 'name'):
        connection.execute(modified_trigger.format(table_name=target.name))

Base = declarative_base()

event.listen(Base.metadata,'after_create', create_modified_trigger)

我以为我可以使用target参数找到table_name,如in the docs所示,但是当与Base.metadata一起使用时,它返回MetaData(bind=None),而不是一个表。在

我强烈希望将此功能作为基础的一部分,而不是将其包含在迁移或外部,以减少有人忘记添加触发器的可能性。这可能吗?在


Tags: name功能eventtargetbasecreatetableupdate
1条回答
网友
1楼 · 发布于 2024-04-26 19:01:38

我在同事的帮助下解决了这个问题。返回的MetaData对象实际上有一个表列表。工作代码如下:

modified_trigger = """
CREATE TRIGGER update_{table_name}_modified
BEFORE UPDATE ON {table_name}
FOR EACH ROW EXECUTE PROCEDURE update_modified_columns()
"""

def create_modified_trigger(target, connection, **kwargs):
    """
    This is used to add bookkeeping triggers after a table is created. It hooks
    into the SQLAlchemy event system. It expects the target to be an instance of
    MetaData.
    """
    for key in target.tables:
        table = target.tables[key]
        connection.execute(modified_trigger.format(table_name=table.name))

Base = declarative_base()

event.listen(Base.metadata, 'after_create', create_modified_trigger)

相关问题 更多 >