如何获得蒸馏器发出的after_create定制DDL?(How do I get alembic

2019-09-16 05:23发布

我有一对夫妇,我想运行后创建表的自定义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();

但是,当我使用升级蒸馏器,语句不会出现:

-- 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');

有没有办法让蒸馏器来触发“after_create”事件?

Answer 1:

表级别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实例,这可能不是你想要的蒸馏器脚本看到。 在蒸馏器create_table命令创建一个Table在本地,只是运行在其上创建,所以你要听全球所有表对象:

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

如果这些事件仅这一个特定的表,虽然,那么你就不会使用任何事件,你只是把DDL()对于那些触发直接在您的迁移脚本,右后它调用create_table()



Answer 2:

扩大对@ zzzeek的答案,这个助手为我工作:

from sqlalchemy import Table
from sqlalchemy.event import listen
from functools import partial

def on_table_create(class_, ddl):

    def listener(tablename, ddl, table, bind, **kw):
        if table.name == tablename:
            ddl(table, bind, **kw)

    listen(Table,
           'after_create',
           partial(listener, class_.__table__.name, ddl))

然后,你会怎么做:

on_table_create(Session, update_function)
on_table_create(Session, update_trigger)


文章来源: How do I get alembic to emit custom DDL on after_create?