1. idank
  2. sqlalchemy

Commits

Mike Bayer  committed c76848b

made mapper compilation "check for remaining mappers" compile anything found, guaranteeing everything to be compiled in all cases

  • Participants
  • Parent commits df98f0a
  • Branches default

Comments (0)

Files changed (3)

File CHANGES

View file
  • Ignore whitespace
 in order of primary key values, for more deterministic ordering
 - after_insert/delete/update mapper extensions now called per object,
 not per-object-per-table
+- fixed the last few mapper compilation stragglers (hopefully)
 
 0.2.4
 - try/except when the mapper sets init.__name__ on a mapped class,

File lib/sqlalchemy/orm/__init__.py

View file
  • Ignore whitespace
 """
 from sqlalchemy import sql, schema, engine, util, exceptions
 from mapper import *
-from mapper import mapper_registry
+from mapper import mapper_registry, _compile_triggers
 from query import Query
 from util import polymorphic_union
 import properties
     """removes all mappers that have been created thus far.  when new mappers are 
     created, they will be assigned to their classes as their primary mapper."""
     mapper_registry.clear()
+    _compile_triggers.clear()
     
 def clear_mapper(m):
     """removes the given mapper from the storage of mappers.  when a new mapper is 

File lib/sqlalchemy/orm/mapper.py

View file
  • Ignore whitespace
     def add_dependency(self, classkey):
         self.dependencies.add(classkey)
     def can_compile(self):
-        #print "can compile", self.mapper, self.dependencies
         return len(self.dependencies) == 0 or (len(self.dependencies)==1 and list(self.dependencies)[0] == self.mapper.class_key)
     def compiled(self, classkey):
         self.dependencies.remove(classkey)
     def __str__(self):
         return "CompileTrigger on mapper " + str(self.mapper)
-            
+    def __repr__(self):
+        return str(self)
+                
 class Mapper(object):
     """Persists object instances to and from schema.Table objects via the sql package.
     Instances of this class should be constructed through this package's mapper() or
             
         self._do_compile()
         
-        # see if other mappers still need to be compiled.  if so,
-        # locate one which is ready to be compiled, and compile it.
+        # find other mappers that need to be compiled, and/or
+        # clean out the _compile_triggers dictionary.
         # this will keep the chain of compilation going until all
         # mappers are compiled.
         for key in _compile_triggers.keys():
             if isinstance(key, ClassKey):
                 mapper = mapper_registry.get(key, None)
+                if mapper.__is_compiled:
+                    del _compile_triggers[key]
+                    continue
                 if mapper is not None:
-                    trigger = _compile_triggers.get(mapper, None)
-                    if trigger is None or trigger.can_compile():
-                        mapper.compile()
-                        break
+                    mapper.compile()
+                    break
         
-        # in most cases, all known mappers should be compiled at this point
-        # _compile_triggers.clear()
-        # assert  len(_compile_triggers) == 0
+        # all known mappers should be compiled at this point
+        assert len(_compile_triggers) == 0
         
         return self
 
                 rec.compiled(self.class_key)
                 if rec.can_compile():
                     rec.mapper._do_compile()
-                    
         return self
 
     def _add_compile_trigger(self, argument):