2013-05-18 2 views
7

는 내가 테이블 생성 후 실행하려면 사용자 정의 DDL 문 몇있어 :after_create에서 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을, 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(); 

하지만 증류기를 사용하여 업그레이드 할 때, 문이 나타나지 않습니다 : SQL을 얻을 나는 기대

-- 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'이벤트를 트리거하려면 alembic을 얻을 수있는 방법이 있습니까?

답변

8

테이블 레벨 before_create/after_create 이벤트가 방출됩니다 (메타 데이터 레벨 레벨은 아님). env.py 스크립트에서 일어나는 일이 궁극적으로 설정되는 이벤트 리스너를 포함하는지 확인해야합니다. 단지 하나의 Table 인스턴스를 것 여기

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

Session.__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()을 호출하면됩니다.

+0

감사합니다. –

4

는 @의 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)