On Feb 9, 2012, at 1:33 PM, Chris Withers wrote:

> On 09/02/2012 15:47, Chris Withers wrote:
>> My thinking was leaning towards actually abandoning the full declarative
>> base and coming up with a light weight one (or maybe even class
>> decorator) that basically added recorded the class in a sequence (much
>> like the declarative reflection does) and then calls
>> instrument_declarative with each class at the point of relfection.


OK I'm not sure if you are on 0.7.5 but the string name of the column is 
accepted for "polymorphic_on".    The recipe just needs to fill in the 
'inherits' keyword within prepare(), and that's it.  See below:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.orm.util import _is_mapped_class
from sqlalchemy.ext.declarative import declarative_base, declared_attr

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(0)
            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)

            for c in klass.__bases__:
                if _is_mapped_class(c):
                    kw['inherits'] = c
                    break

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

Base = declarative_base()

class Reflected(DeclarativeReflectedBase, Base):
    __abstract__ = True

class GeneralType(Reflected):
   __tablename__ = 'single_inherits'
   __mapper_args__ = dict(polymorphic_on='type')

class TypeOne(GeneralType):
   __mapper_args__ = dict(polymorphic_identity='one')

class TypeTwo(GeneralType):
   __mapper_args__ = dict(polymorphic_identity='two')

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

Reflected.prepare(e)

s = Session(e)

s.add_all([
    TypeOne(type="one"), TypeOne(type="one"), TypeTwo(type="two")
])
s.commit()
s.close()
print s.query(GeneralType).all()



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

Reply via email to