]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
Got the unit tests running again, apart from the two that were not working in
authorJonathan LaCour <jonathan@cleverdevil.org>
Sun, 23 Apr 2006 21:41:36 +0000 (21:41 +0000)
committerJonathan LaCour <jonathan@cleverdevil.org>
Sun, 23 Apr 2006 21:41:36 +0000 (21:41 +0000)
the first place.  The changes to process_relationships and to sqlachemy itself
were causing a double 'assign_mapper' call to cause issues.  Now, we basically
defer calling assign_mapper until process_relationships in cases where there
are defined relationships.

Also, I moved ActiveMapper to always use the default engine, as there were a
lot of hacks inside ActiveMapper to allow for engine swapping.  The use of the
default engine and the "global_connect" functionality significantly improves
the usability of ActiveMapper.

ActiveMapper will be getting a bit of a refactor/cleanup at some point in the
nearish future, as it has drifted a bit to complexity with the addition of some
features.  For now, this should do the trick!

lib/sqlalchemy/ext/activemapper.py
test/activemapper.py

index 4b2b9055a8f2e56d383c51d4e4500067841f35d2..f875b30b3338dea36e6e0d154a87a017f116aaf1 100644 (file)
@@ -1,18 +1,9 @@
-from sqlalchemy             import objectstore, create_engine, assign_mapper, relation, mapper, join
-from sqlalchemy             import and_, or_
+from sqlalchemy             import assign_mapper, relation, exceptions
 from sqlalchemy             import Table, Column, ForeignKey
-from sqlalchemy.ext.proxy   import ProxyEngine
 
 import inspect
 import sys
 
-#
-# the "proxy" to the database engine... this can be swapped out at runtime
-#
-engine = ProxyEngine()
-
-
-
 #
 # declarative column declaration - this is so that we can infer the colname
 #
@@ -87,22 +78,21 @@ def check_relationships(klass):
 def process_relationships(klass):
     defer = False
     for propname, reldesc in klass.relations.items():
-        #We require that every related table has been processed first
+        # we require that every related table has been processed first
         if not reldesc.classname in __processed_classes__:
             if not klass._classname in __deferred_classes__: __deferred_classes__.append(klass._classname)
             defer = True
-
-
-    #Check every column item to see if it points to an existing table
-    #if it does not, defer...
+    
+    # check every column item to see if it points to an existing table
+    # if it does not, defer...
     if not defer:
-            if not check_relationships(klass):
-                if not klass._classname in __deferred_classes__: __deferred_classes__.append(klass._classname)
-                defer = True
-
+        if not check_relationships(klass):
+            if not klass._classname in __deferred_classes__: __deferred_classes__.append(klass._classname)
+            defer = True
+    
     if not defer:
         relations = {}
-        __processed_classes__.append(klass._classname)
+        
         for propname, reldesc in klass.relations.items():
             relclass = ActiveMapperMeta.classes[reldesc.classname]
             relations[propname] = relation(relclass.mapper,
@@ -111,17 +101,23 @@ def process_relationships(klass):
                                            private=reldesc.private, 
                                            lazy=reldesc.lazy, 
                                            uselist=reldesc.uselist)
-        if len(relations)>0:
-            assign_mapper(klass, klass.table, properties=relations)
-
-        if klass._classname in __deferred_classes__: __deferred_classes__.remove(klass._classname)
+        if len(relations) > 0:
+            assign_ok = True
+            try:
+                assign_mapper(klass, klass.table, properties=relations)
+            except exceptions.ArgumentError:
+                assign_ok = False
+
+            if assign_ok:
+                __processed_classes__.append(klass._classname)
+                if klass._classname in __deferred_classes__: __deferred_classes__.remove(klass._classname)
+        else:
+            __processed_classes__.append(klass._classname)
 
         for deferred_class in __deferred_classes__:
             process_relationships(ActiveMapperMeta.classes[deferred_class])
 
 
-
-
 class ActiveMapperMeta(type):
     classes = {}
 
@@ -129,7 +125,6 @@ class ActiveMapperMeta(type):
         table_name = clsname.lower()
         columns    = []
         relations  = {}
-        _engine    = getattr( sys.modules[cls.__module__], "__engine__", engine )
 
         if 'mapping' in dict:
             members = inspect.getmembers(dict.get('mapping'))
@@ -138,10 +133,6 @@ class ActiveMapperMeta(type):
                     table_name = value
                     continue
 
-                if '__engine__' == name:
-                    _engine= value
-                    continue
-
                 if name.startswith('__'): continue
 
                 if isinstance(value, column):
@@ -161,13 +152,14 @@ class ActiveMapperMeta(type):
 
                 if isinstance(value, relationship):
                     relations[name] = value
-            assert _engine is not None, "No engine specified"
-            cls.table = Table(table_name, _engine, *columns)
+            
+            cls.table = Table(table_name, redefine=True, *columns)
+            
             # check for inheritence
-            if hasattr( bases[0], "mapping" ):
-                cls._base_mapper= bases[0].mapper
+            if hasattr(bases[0], "mapping"):
+                cls._base_mapper = bases[0].mapper
                 assign_mapper(cls, cls.table, inherits=cls._base_mapper)
-            else:
+            elif len(relations) == 0:
                 assign_mapper(cls, cls.table)
             cls.relations = relations
             cls._classname = clsname
@@ -191,4 +183,11 @@ class ActiveMapper(object):
 
 def create_tables():
     for klass in ActiveMapperMeta.classes.values():
-        klass.table.create()
\ No newline at end of file
+        klass.table.create()
+
+#
+# a utility function to drop all tables for all ActiveMapper classes
+#
+def drop_tables():
+    for klass in ActiveMapperMeta.classes.values():
+        klass.table.drop()
\ No newline at end of file
index edb49fea34772a128385d30f36611398d5d85d51..7edb414880b2b02b7bf23ea359823c98ab32677a 100644 (file)
@@ -1,11 +1,11 @@
-from activemapper           import ActiveMapper, column, one_to_many, one_to_one
-from sqlalchemy             import objectstore
-from sqlalchemy             import and_, or_
-from sqlalchemy             import ForeignKey, String, Integer, DateTime
-from datetime               import datetime
+from sqlalchemy.ext.activemapper    import ActiveMapper, column, one_to_many, one_to_one
+from sqlalchemy.ext                 import activemapper
+from sqlalchemy                     import objectstore, global_connect
+from sqlalchemy                     import and_, or_
+from sqlalchemy                     import ForeignKey, String, Integer, DateTime
+from datetime                       import datetime
 
 import unittest
-import activemapper
 
 #
 # application-level model objects
@@ -130,6 +130,9 @@ class testcase(unittest.TestCase):
     
     
     def test_create(self):
+        global_connect('sqlite:///', echo=False)
+        activemapper.create_tables()
+        
         p1 = self.create_person_one()
         
         objectstore.commit()
@@ -222,9 +225,4 @@ class testcase(unittest.TestCase):
 
     
 if __name__ == '__main__':
-    # go ahead and setup the database connection, and create the tables
-    activemapper.engine.connect('sqlite:///', echo=False)
-    activemapper.create_tables()
-    
-    # launch the unit tests
     unittest.main()
\ No newline at end of file