diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-03 13:46:41 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2013-12-03 13:46:41 -0500 |
commit | 36e1aa0afdf7e42f88426da4b2e9ee631d16728c (patch) | |
tree | 233b2308824abd1faab762e5df7fbcd815049cad /lib/sqlalchemy/ext/declarative/api.py | |
parent | 21feea9c1d278036cc37add813b72d0dbd4b1754 (diff) | |
download | sqlalchemy-36e1aa0afdf7e42f88426da4b2e9ee631d16728c.tar.gz |
- The :class:`.DeferredReflection` class has been enhanced to provide
automatic reflection support for the "secondary" table referred
to by a :func:`.relationship`. "secondary", when specified
either as a string table name, or as a :class:`.Table` object with
only a name and :class:`.MetaData` object will also be included
in the reflection process when :meth:`.DeferredReflection.prepare`
is called. [ticket:2865]
- clsregistry._resolver() now uses a stateful _class_resolver()
class in order to handle the work of mapping strings to
objects. This is to provide for simpler extensibility, namely
a ._resolvers collection of ad-hoc name resolution functions;
the DeferredReflection class adds its own resolver here in order
to handle relationship(secondary) names which generate new
Table objects.
Diffstat (limited to 'lib/sqlalchemy/ext/declarative/api.py')
-rw-r--r-- | lib/sqlalchemy/ext/declarative/api.py | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/lib/sqlalchemy/ext/declarative/api.py b/lib/sqlalchemy/ext/declarative/api.py index 1cb653a23..64bf7fd9f 100644 --- a/lib/sqlalchemy/ext/declarative/api.py +++ b/lib/sqlalchemy/ext/declarative/api.py @@ -9,15 +9,17 @@ from ...schema import Table, MetaData from ...orm import synonym as _orm_synonym, mapper,\ comparable_property,\ - interfaces + interfaces, properties from ...orm.util import polymorphic_union from ...orm.base import _mapper_or_none +from ...util import compat from ... import exc import weakref from .base import _as_declarative, \ _declarative_constructor,\ _MapperConfig, _add_attribute +from .clsregistry import _class_resolver def instrument_declarative(cls, registry, metadata): @@ -465,11 +467,31 @@ class DeferredReflection(object): def prepare(cls, engine): """Reflect all :class:`.Table` objects for all current :class:`.DeferredReflection` subclasses""" + to_map = [m for m in _MapperConfig.configs.values() if issubclass(m.cls, cls)] for thingy in to_map: cls._sa_decl_prepare(thingy.local_table, engine) thingy.map() + mapper = thingy.cls.__mapper__ + metadata = mapper.class_.metadata + for rel in mapper._props.values(): + if isinstance(rel, properties.RelationshipProperty) and \ + rel.secondary is not None: + if isinstance(rel.secondary, Table): + cls._sa_decl_prepare(rel.secondary, engine) + elif isinstance(rel.secondary, _class_resolver): + rel.secondary._resolvers += ( + cls._sa_deferred_table_resolver(engine, metadata), + ) + + @classmethod + def _sa_deferred_table_resolver(cls, engine, metadata): + def _resolve(key): + t1 = Table(key, metadata) + cls._sa_decl_prepare(t1, engine) + return t1 + return _resolve @classmethod def _sa_decl_prepare(cls, local_table, engine): |