2011-08-24 21 views
8

Ho una domanda su come rendere l'ereditarietà delle tabelle PostgreSQL usando SQLAlchemy.ereditarietà Postgres con SQLAlchemy

ho questo due tabelle:

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

Prima di eseguire qualsiasi comando DDL, ho fatto questo codice 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() 

Beh, questo esempio (come spiegato nel http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PostgreSQLInheritance) creare due tabelle , ma sqlalchemy usa sempre la sua tabella per inserire i record di dati, e questi sono inseriti sui dati e sul suo. il campo di testo (sui dati) è davvero creato sul suo tavolo.

Quindi, c'è un modo per specificare a SQLAchemy che la tabella di dati deve ereditare (Postgres eredita) dal suo, e deve aggiungere un campo di testo ad esso, e deve essere usato i dati e non il suo quando inserisco qualsiasi record sui dati?

Saluti.

risposta