Even though the latest version of the DeclarativeRefletive example
includes some handling for inheritance, I still can not get it to
work. I try doing (mostly modified example from
https://bitbucket.org/sqlalchemy/sqlalchemy/src/408388e5faf4/examples/declarative_reflection/declarative_reflection.py):

from sqlalchemy.types import Integer
from sqlalchemy.types import String
from sqlalchemy.schema import ForeignKey
from sqlalchemy.schema import Column
from sqlalchemy.schema import Table
from sqlalchemy.orm import mapper
from sqlalchemy.orm.session import Session
from sqlalchemy.orm.util import _is_mapped_class
from sqlalchemy.engine import create_engine
from sqlalchemy.ext.declarative import declarative_base

class DeclarativeReflectedBase(object):
    _mapper_args = []

    @classmethod
    def __mapper_cls__(cls, *args, **kw):
        """Declarative will use this function in lieu of
        calling mapper() directly.

        Collect each series of arguments and invoke
        them when prepare() is called.
        """

        cls._mapper_args.append((args, kw))

    @classmethod
    def prepare(cls, engine):
        """Reflect all the tables and map !"""
        while cls._mapper_args:
            args, kw  = cls._mapper_args.pop()
            klass = args[0]
            # autoload Table, which is already
            # present in the metadata.  This
            # will fill in db-loaded columns
            # into the existing Table object.
            if args[1] is not None:
                table = args[1]
                Table(table.name,
                    cls.metadata,
                    extend_existing=True,
                    autoload_replace=False,
                    autoload=True,
                    autoload_with=engine,
                    schema=table.schema)

            # see if we need 'inherits' in the
            # mapper args.  Declarative will have
            # skipped this since mappings weren't
            # available yet.
            for c in klass.__bases__:
                if _is_mapped_class(c):
                    kw['inherits'] = c
                    break

            klass.__mapper__ = mapper(*args, **kw)

if __name__ == '__main__':
    Base = declarative_base()

    # create a separate base so that we can
    # define a subset of classes as "Reflected",
    # instead of everything.
    class Reflected(DeclarativeReflectedBase, Base):
        __abstract__ = True

    class Foo(Reflected):
        __tablename__ = 'foo'

        type_ = Column('type', String(32))
        __mapper_args__ = {'polymorphic_on': type_,
                           'polymorphic_identity': 'foo'}


    class Bar(Foo):
        __tablename__ = 'bar'
        __mapper_args__ = {'polymorphic_identity': 'bar'}

        id = Column(Integer, ForeignKey('foo.id'), primary_key=True)

    e = create_engine('sqlite://', echo=True)
    e.execute("""
    create table foo(
        id integer primary key,
        type varchar(32),
        data varchar(30)
    )
    """)

    e.execute("""
    create table bar(
        id integer primary key,
        bar_data varchar(30)
    )
    """)

    Reflected.prepare(e)

    s = Session(e)

    s.add_all([
        Bar(data='d1', bar_data='b1'),
        Bar(data='d2', bar_data='b2'),
        Bar(data='d3', bar_data='b3'),
        Foo(data='d4')
    ])
    s.commit()
    for f in s.query(Foo):
        print f.data, getattr(f, 'bar_data', 'not_a_bar')

and sqlalchemy tries to find the type column in the table 'bar'. Am I
doing the inheritance set up wrong or is it some bug in
DeclarativeReflectiveBase?

Ignas

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to