简体   繁体   English

使用SQLAlchemy进行Postgres继承

[英]Postgres inheritance with SQLAlchemy

I have one question about make PostgreSQL table inheritance using SQLAlchemy. 我有一个关于使用SQLAlchemy制作PostgreSQL表继承的问题。

I have this two tables: 我有这两个表:

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

Before execute any ddl command, I have made this python code: 在执行任何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()

Well, this example (like explained in http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PostgreSQLInheritance ) create two tables, but sqlalchemy always use his table to insert data records, and these are inserted on data and his. 好吧,这个例子(如http://www.sqlalchemy.org/trac/wiki/UsageRecipes/PostgreSQLInheritance中所述 )创建了两个表,但是sqlalchemy总是使用他的表来插入数据记录,并将这些表插入到数据和他的数据中。 text field (on data) is really created on his table. 文本字段(在数据上)确实是在他的表上创建的。

So, is there any way to specify to SQLAchemy that data table must inherits (Postgres inherits) from his, and must add text field to it, and must be used data and not his when I insert any record on data? 那么,有没有办法指定SQLAchemy数据表必须从他继承(Postgres继承),并且必须向其添加文本字段,并且当我在数据上插入任何记录时必须使用数据而不是他的数据?

Regards. 问候。

SQLAlchemy tries to be as portable as possible so it doesn't support many Postgres-specific features. SQLAlchemy试图尽可能地移植,因此它不支持许多Postgres特有的功能。 Here is an answer given from SA guy to someone with similar problem: http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg17443.html 以下是SA家伙给出类似问题的答案: http//www.mail-archive.com/sqlalchemy@googlegroups.com/msg17443.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM