Наследование Postgres с помощью SQLAlchemy - PullRequest
9 голосов
/ 24 августа 2011

У меня один вопрос по поводу наследования таблиц PostgreSQL с использованием 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 я сделал такой код:

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 наследует) от его и должна добавлять к нему текстовое поле, и должны использоваться данные, а не его, когда я вставляю какую-либо запись в данные?

Привет.

1 Ответ

2 голосов
/ 11 октября 2011

SQLAlchemy старается быть максимально переносимым, поэтому он не поддерживает многие специфичные для Postgres функции. Вот ответ, данный парнем из SA кому-то с подобной проблемой: http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg17443.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...