- changed milestone to 0.7.5
possible rearrangement of history_meta based on events
Issue #2313
resolved
which has to be a new event too...
diff -r 5d6376fbd5ca4103a26118a6fffd1e95be0d5161 examples/versioning/history_meta.py
--- a/examples/versioning/history_meta.py Fri Oct 28 17:46:28 2011 -0400
+++ b/examples/versioning/history_meta.py Fri Oct 28 18:46:27 2011 -0400
@@ -1,7 +1,7 @@
from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.orm import mapper, class_mapper, attributes, object_mapper
from sqlalchemy.orm.exc import UnmappedClassError, UnmappedColumnError
-from sqlalchemy import Table, Column, ForeignKeyConstraint, Integer
+from sqlalchemy import Table, Column, ForeignKeyConstraint, Integer, event
from sqlalchemy.orm.interfaces import SessionExtension
from sqlalchemy.orm.properties import RelationshipProperty
@@ -13,6 +13,9 @@
def _history_mapper(local_mapper):
cls = local_mapper.class_
+ if '__history_mapper__' in cls.__dict__ or \
+ hasattr(cls, '_is_history'):
+ return
# set the "active_history" flag
# on on column-mapped attributes so that the old version
@@ -25,6 +28,7 @@
polymorphic_on = None
super_fks = [ if not super_mapper or local_mapper.local_table is not super_mapper.local_table:
cols = [](]
+
)
for column in local_mapper.local_table.c:
@@ -68,7 +72,7 @@
bases = (super_history_mapper.class_,)
else:
bases = local_mapper.base_mapper.class_.__bases__
- versioned_cls = type.__new__(type, "%sHistory" % cls.__name__, bases, {})
+ versioned_cls = type.__new__(type, "%sHistory" % cls.__name__, bases, {'_is_history':True})
m = mapper(
versioned_cls,
@@ -80,19 +84,19 @@
cls.__history_mapper__ = m
if not super_history_mapper:
- cls.version = Column('version', Integer, default=1, nullable=False)
+ col = Column('version', Integer, default=1, nullable=False)
+ local_mapper.local_table.append_column(col)
+ local_mapper.add_property('version', col)
class VersionedMeta(DeclarativeMeta):
- def __init__(cls, classname, bases, dict_):
- DeclarativeMeta.__init__(cls, classname, bases, dict_)
+ pass
- try:
- mapper = class_mapper(cls)
- _history_mapper(mapper)
- except UnmappedClassError:
- pass
+@event.listens_for(mapper, "mapper_constructed")
+def setup_history_mapper(mapper, cls):
+ if isinstance(cls, VersionedMeta):
+ _history_mapper(mapper)
def versioned_objects(iter):
for obj in iter:
diff -r 5d6376fbd5ca4103a26118a6fffd1e95be0d5161 lib/sqlalchemy/orm/events.py
--- a/lib/sqlalchemy/orm/events.py Fri Oct 28 17:46:28 2011 -0400
+++ b/lib/sqlalchemy/orm/events.py Fri Oct 28 18:46:27 2011 -0400
@@ -385,6 +385,21 @@
"""
+ def mapper_constructed(self, mapper, class_):
+ """Called when the mapper is finished constructed, but not yet
+ configured.
+
+ Events that wish to create new mappers as a result
+ of a previous mapping should go here, as the mapper is
+ mostly ready, but we aren't out of the "we've compiled all
+ the mappers" phase.
+
+ :param mapper: the :class:`.Mapper` which is the target
+ of this event.
+ :param class\_: the mapped class.
+
+ """
+
def mapper_configured(self, mapper, class_):
"""Called when the mapper for the class is fully configured.
diff -r 5d6376fbd5ca4103a26118a6fffd1e95be0d5161 lib/sqlalchemy/orm/mapper.py
--- a/lib/sqlalchemy/orm/mapper.py Fri Oct 28 17:46:28 2011 -0400
+++ b/lib/sqlalchemy/orm/mapper.py Fri Oct 28 18:46:27 2011 -0400
@@ -207,6 +207,7 @@
_new_mappers = True
self._log("constructed")
self._expire_memoizations()
+ self.dispatch.mapper_constructed(self, self.class_)
finally:
_COMPILE_MUTEX.release()
@@ -2798,7 +2799,12 @@
mapper._configure_failed = exc
raise
+ # TODO: if a "mapper configured" event
+ # creates a new mapper, then this
+ # is wrong. however, a simple move
+ # up above is failing some tests.
_new_mappers = False
+
finally:
_already_compiling = False
finally:
we'd want to test this against AbstractConcreteBase
.
Comments (3)
-
reporter -
reporter - changed status to resolved
82e4bc2f52f2d420842819d0ffe548ca968bf54e just uses a mixin.
-
reporter - removed milestone
Removing milestone: 0.7.5 (automated comment)
- Log in to comment
this is really an 0.7.xx thing but we'll bump it for awhile