summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/declarative/api.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-12-03 13:46:41 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2013-12-03 13:46:41 -0500
commit36e1aa0afdf7e42f88426da4b2e9ee631d16728c (patch)
tree233b2308824abd1faab762e5df7fbcd815049cad /lib/sqlalchemy/ext/declarative/api.py
parent21feea9c1d278036cc37add813b72d0dbd4b1754 (diff)
downloadsqlalchemy-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.py24
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):