From 22a0e600ce937cea4ea691d209f592e25c77d6a4 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Fri, 7 Jul 2006 21:32:30 +0000 Subject: [PATCH] made mapper compilation "check for remaining mappers" compile anything found, guaranteeing everything to be compiled in all cases --- CHANGES | 1 + lib/sqlalchemy/orm/__init__.py | 3 ++- lib/sqlalchemy/orm/mapper.py | 24 ++++++++++++------------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index ee17260345..7f8a4f4b7c 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ working around new setuptools PYTHONPATH-killing behavior 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, diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py index 8b7d3df0b7..9ebeffab89 100644 --- a/lib/sqlalchemy/orm/__init__.py +++ b/lib/sqlalchemy/orm/__init__.py @@ -10,7 +10,7 @@ packages and tying operations to class properties and constructors. """ 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 @@ -52,6 +52,7 @@ def clear_mappers(): """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 diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 120c5f2094..186963f316 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -41,13 +41,14 @@ class CompileTrigger(object): 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 @@ -177,22 +178,22 @@ class Mapper(object): 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 @@ -224,7 +225,6 @@ class Mapper(object): rec.compiled(self.class_key) if rec.can_compile(): rec.mapper._do_compile() - return self def _add_compile_trigger(self, argument): -- 2.47.2