]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- [feature] Added "class_registry" argument to
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 28 Dec 2011 16:10:49 +0000 (11:10 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 28 Dec 2011 16:10:49 +0000 (11:10 -0500)
declarative_base().  Allows two or more declarative
bases to share the same registry of class names.

CHANGES
lib/sqlalchemy/ext/declarative.py
test/ext/test_declarative.py

diff --git a/CHANGES b/CHANGES
index f5540e1e0f1807c2d8ecb37f04fa3c79c9f9dc90..56aede3c88131d8970ef820542a6e4d68bda43b5 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,10 @@ CHANGES
   - [bug] Fixed bug whereby hybrid_property didn't 
     work as a kw arg in any(), has().
 
+  - [feature] Added "class_registry" argument to
+    declarative_base().  Allows two or more declarative
+    bases to share the same registry of class names.
+
 - Py3K
   - [bug] Fixed inappropriate usage of util.py3k
     flag and renamed it to util.py3k_warning, since 
index 91d770197c89729d1959f0312b7971e3658c66bb..dc84c5dfb6356d9428880a8e37834517af976ab4 100755 (executable)
@@ -1500,6 +1500,7 @@ _declarative_constructor.__name__ = '__init__'
 
 def declarative_base(bind=None, metadata=None, mapper=None, cls=object,
                      name='Base', constructor=_declarative_constructor,
+                     class_registry=None,
                      metaclass=DeclarativeMeta):
     """Construct a base class for declarative class definitions.
 
@@ -1543,6 +1544,13 @@ def declarative_base(bind=None, metadata=None, mapper=None, cls=object,
       no __init__ will be provided and construction will fall back to
       cls.__init__ by way of the normal Python semantics.
 
+    :param class_registry: optional dictionary that will serve as the 
+      registry of class names-> mapped classes when string names
+      are used to identify classes inside of :func:`.relationship` 
+      and others.  Allows two or more declarative base classes
+      to share the same registry of class names for simplified 
+      inter-base relationships.
+      
     :param metaclass:
       Defaults to :class:`.DeclarativeMeta`.  A metaclass or __metaclass__
       compatible callable to use as the meta type of the generated
@@ -1553,8 +1561,11 @@ def declarative_base(bind=None, metadata=None, mapper=None, cls=object,
     if bind:
         lcl_metadata.bind = bind
 
+    if class_registry is None:
+        class_registry = {}
+
     bases = not isinstance(cls, tuple) and (cls,) or cls
-    class_dict = dict(_decl_class_registry=dict(),
+    class_dict = dict(_decl_class_registry=class_registry,
                       metadata=lcl_metadata)
 
     if constructor:
index 2e2989a646a94d5335a861ab1b47bd82602bd37a..3069c2bfece364523981a978e1e2bc9bd57bb2eb 100644 (file)
@@ -368,6 +368,23 @@ class DeclarativeTest(DeclarativeTestBase):
         assert class_mapper(User).get_property('props').secondary \
             is user_to_prop
 
+    def test_shared_class_registry(self):
+        reg = {}
+        Base1 = decl.declarative_base(testing.db, class_registry=reg)
+        Base2 = decl.declarative_base(testing.db, class_registry=reg)
+
+        class A(Base1):
+            __tablename__ = 'a'
+            id = Column(Integer, primary_key=True)
+
+        class B(Base2):
+            __tablename__ = 'b'
+            id = Column(Integer, primary_key=True)
+            aid = Column(Integer, ForeignKey(A.id))
+            as_ = relationship("A")
+
+        assert B.as_.property.mapper.class_ is A
+
     def test_uncompiled_attributes_in_relationship(self):
 
         class Address(Base, fixtures.ComparableEntity):