2011-08-24 83 views
8

我有一個問題關於使用SQLAlchemy的,讓PostgreSQL表繼承。Postgres的繼承與SQLAlchemy的

我有這兩個表:

CREATE TABLE his 
(
    idg integer, 
    idfk integer, 
    idh integer NOT NULL defautl nextval('his_seq'), 
    "type" character varying, 
    CONSTRAINT __his_pkey PRIMARY KEY (idh) 
); 
CREATE TABLE data 
(
    "text" character varying, 
) 
INHERITS (his); 

之前執行任何DDL命令,我做了這個Python代碼:

from sqlalchemy import * 
from sqlalchemy.orm import Session 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy import event 

Base = declarative_base() 

class His(Base): 
    __tablename__ = 'his' 

    idg = Column(Integer()) 
    idfk = Column(Integer()) 
    idh = Column(Integer(), Sequence('his_seq', start=1, increment=1), primary_key=True) 
    type= Column(String()) 

    __mapper_args__ = {'polymorphic_on': type} 
    __table_args__ = {'implicit_returning':False} 

    def __init__(self, idg, idfk, type): 
     self.idg = idg 
     self.idfk = idfk 
     self.type = type 

class Data(His): 
    __tablename__ = None 
# __mapper_args__ = {'polymorphic_identity': 'data', 'concrete':True} 
    __mapper_args__ = {'polymorphic_identity': 'data'} 
    text = Column(String()) 

    def __init__(self, text): 
     self.text = text 

@event.listens_for(His.__table__, 'after_create') 
def create_child_tables(target, connection, **kw): 
    connection.execute(""" 
     CREATE TABLE data(
     ) INHERITS (his) 
    """) 

    connection.execute(""" 
     CREATE OR REPLACE FUNCTION his_insert_trigger() 
     RETURNS TRIGGER AS $$ 
     BEGIN 
      IF (NEW.type='data') THEN 
       INSERT INTO data VALUES (NEW.*); 
      ELSE 
       RAISE EXCEPTION 'Table type is unknown for historical porpurses.'; 
      END IF; 
     RETURN NULL; 
     END; 
     $$ 
     LANGUAGE plpgsql;  
    """) 

    connection.execute(""" 
     CREATE TRIGGER his_insert 
     BEFORE INSERT ON his 
     FOR EACH ROW EXECUTE PROCEDURE his_insert_trigger(); 
    """) 

@event.listens_for(His.__table__, "before_drop") 
def create_child_tables(target, connection, **kw): 
    connection.execute("drop table data") 
    connection.execute("drop table his") 
    connection.execute("drop sequence his_seq") 

e = create_engine('postgresql://localhost:5433/des', echo=True) 
#Base.metadata.drop_all(e) 
Base.metadata.create_all(e) 
s = Session(e) 

s.add_all([ 
    Data('hola'), 
    Data('pedorrete'), 
    Data('pedorrete2') 
]) 

s.commit() 
s.close() 

嗯,這個例子(如在http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PostgreSQLInheritance解釋)創建兩個表,但sqlalchemy總是使用他的表來插入數據記錄,並將這些記錄插入數據和他的。文本字段(數據)真的在他的桌子上創建。

那麼,有沒有什麼辦法來指定SQLAchemy數據表必須繼承(Postgres的繼承)從他的,而且必須文本字段添加到它,當我插上數據的任何記錄必須使用的數據,而不是他的?

問候。

回答