2013-05-18 21 views
7

Tôi đã có một vài tùy chỉnh lệnh DDL mà tôi muốn chạy sau khi tạo bảng:Làm cách nào để nhận được alembic phát ra DDL tùy chỉnh trên after_create?

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(); 
""") 

Và tôi đã gắn cho họ như thế này:

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

Khi tôi làm create_all, tôi có được SQL tôi mong đợi:

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

Nhưng khi tôi nâng cấp sử dụng nồi cất rượu, những điều khoản không xuất hiện:

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

Có cách nào để nhận alembic kích hoạt sự kiện 'after_create' không?

Trả lời

8

Sự kiện before_create/after_create ở mức bảng được phát ra (không chỉ các sự kiện cấp siêu dữ liệu). bạn cần phải chắc chắn rằng bất cứ điều gì xảy ra trong kịch bản env.py của bạn cuối cùng liên quan đến những người nghe sự kiện đang được thiết lập.

Mã bạn có ở đây trông một chút nghi ngờ:

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

Session.__table__ ở đây sẽ chỉ là một Table trường hợp duy nhất và đó có lẽ không phải những gì bạn thấy trong kịch bản nồi cất rượu. Các nồi cất rượu create_table lệnh tạo ra một Table tại địa phương và chỉ cần chạy một tạo trên nó, vì vậy bạn cần phải lắng nghe tất cả các đối tượng trên toàn cầu Bảng:

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

nếu những sự kiện này chỉ dành cho một bảng cụ thể này, mặc dù sau đó bạn sẽ không sử dụng bất kỳ sự kiện nào, bạn chỉ cần đặt DDL() cho những trình kích hoạt đó trực tiếp trong tập lệnh di chuyển của bạn, ngay sau khi nó gọi create_table().

+0

Cảm ơn lời giải thích. –

4

Mở rộng về câu trả lời @ zzzeek của, helper này làm việc cho tôi:

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

Sau đó, bạn sẽ làm:

on_table_create(Session, update_function) 
on_table_create(Session, update_trigger) 
Các vấn đề liên quan