postgresql - 如何让 alembic 在 after_create 上发出自定义 DDL?

标签 postgresql sqlalchemy ddl alembic

我有几个自定义 DDL 语句,我想在创建表后运行它们:

update_function = DDL("""                                                                                                                                                       
CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = now();
    RETURN NEW;
END;
$$ language 'pgplsql';
""")

update_trigger = DDL("""
CREATE TRIGGER update %(table)s_timestamp BEFORE UPDATE
ON %(table)s FOR EACH ROW EXECUTE PROCEDURE update_timestamp();
""")

我已经像这样附加了它们:

event.listen(Session.__table__, 'after_create', update_function)
event.listen(Session.__table__, 'after_create', update_trigger)

当我执行 create_all 时,我得到了我期望的 SQL:

CREATE OR REPLACE FUNCTION update_timestamp()
RETURNS TRIGGER AS $$ 
BEGIN
    NEW.updated_at = now();
    RETURN NEW;
END;
$$ language 'pgplsql';


CREATE TRIGGER update session_timestamp BEFORE UPDATE
ON session FOR EACH ROW EXECUTE PROCEDURE update_timestamp();

但是当我使用 Alembic 升级时,语句不会出现:

-- Running upgrade c0d470e5c81 -> 6692fad7378

CREATE TABLE session (
    created_at TIMESTAMP WITHOUT TIME ZONE DEFAULT 'CURRENT_TIMESTAMP', 
    updated_at TIMESTAMP WITHOUT TIME ZONE DEFAULT 'CURRENT_TIMESTAMP', 
    id VARCHAR(32) NOT NULL, 
    owner_id INTEGER, 
    database_id VARCHAR(32), 
    content TEXT, 
    PRIMARY KEY (id), 
    FOREIGN KEY(database_id) REFERENCES database (id), 
    FOREIGN KEY(owner_id) REFERENCES users (id)
);

INSERT INTO alembic_version (version_num) VALUES ('6692fad7378');

有没有办法让 alembic 触发“after_create”事件?

最佳答案

表级别 before_create/after_create 事件被发出(只是不是元数据级别的)。您需要确保您的 env.py 脚本中发生的任何事情最终都涉及正在设置的事件监听器。

这里的代码看起来有点可疑:

event.listen(Session.__table__, 'after_create', update_function)
event.listen(Session.__table__, 'after_create', update_trigger)

Session.__table__ 这里只是一个 Table 实例,这可能不是您在 alembic 脚本中看到的。 alembic create_table 命令在本地创建一个 Table 并在其上运行一个创建,因此您需要全局监听所有 Table 对象:

from sqlalchemy import Table
event.listen(Table, 'after_create', update_function)
event.listen(Table, 'after_create', update_trigger)

如果这些事件只针对这个特定的表,那么您将不会使用任何事件,您只需将这些触发器的 DDL() 直接放在迁移脚本中,就在它调用 的位置之后创建表()

关于postgresql - 如何让 alembic 在 after_create 上发出自定义 DDL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16629037/

相关文章:

mysql - 内存消耗和正确的数据库设计

python - 解析 sqlalchemy 存储过程执行的结果

sql - 将数据移动到另一个表

postgresql - 将 byte[] PBEKeySpec 存储到 openshift 齿轮表现不同?

postgresql - 在 Amazon RDS 上设置 PostGis

postgresql - ALTER COLUMN TYPE varchar(N) 是否重写 Postgres 9.6 中的表?

Java JDBC : Altering table

java - 获取列的名称 (PostgreSQL)

python - 在 Flask + SQLAlchemy 中设置一对一关系

hadoop - Hive 1.1.0 将表分区类型从 int 更改为 string