diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-05-16 11:26:04 -0400 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2019-05-16 11:28:44 -0400 |
| commit | 5039c6f01d0bd1f58f950e80cddf7472444a70a4 (patch) | |
| tree | a21d629a13ef4d0f7a5129cd9fdc5f6164bfbd1e /lib/sqlalchemy/ext/declarative | |
| parent | 89e6beaf46ebdd626e292eb20f7b6ae0c3a9ae5c (diff) | |
| download | sqlalchemy-5039c6f01d0bd1f58f950e80cddf7472444a70a4.tar.gz | |
Mutex the declarative scan/map process against configure_mappers()
Applied the mapper "configure mutex" against the declarative class mapping
process, to guard against the race which can occur if mappers are used
while dynamic module import schemes are still in the process of configuring
mappers for related classes. This does not guard against all possible race
conditions, such as if the concurrent import has not yet encountered the
dependent classes as of yet, however it guards against as much as possible
within the SQLAlchemy declarative process.
Fixes: #4686
Change-Id: I0349036b8078bd42265ab40862cfbfe5bf9d5b44
Diffstat (limited to 'lib/sqlalchemy/ext/declarative')
| -rw-r--r-- | lib/sqlalchemy/ext/declarative/base.py | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/lib/sqlalchemy/ext/declarative/base.py b/lib/sqlalchemy/ext/declarative/base.py index 62db282d1..622a83736 100644 --- a/lib/sqlalchemy/ext/declarative/base.py +++ b/lib/sqlalchemy/ext/declarative/base.py @@ -17,6 +17,7 @@ from ... import util from ...orm import class_mapper from ...orm import exc as orm_exc from ...orm import mapper +from ...orm import mapperlib from ...orm import synonym from ...orm.attributes import QueryableAttribute from ...orm.base import _is_mapped_class @@ -155,6 +156,7 @@ class _MapperConfig(object): cfg_cls = _DeferredMapperConfig else: cfg_cls = _MapperConfig + cfg_cls(cls_, classname, dict_) def __init__(self, cls_, classname, dict_): @@ -177,17 +179,21 @@ class _MapperConfig(object): self._scan_attributes() - clsregistry.add_class(self.classname, self.cls) + mapperlib._CONFIGURE_MUTEX.acquire() + try: + clsregistry.add_class(self.classname, self.cls) - self._extract_mappable_attributes() + self._extract_mappable_attributes() - self._extract_declared_columns() + self._extract_declared_columns() - self._setup_table() + self._setup_table() - self._setup_inheritance() + self._setup_inheritance() - self._early_mapping() + self._early_mapping() + finally: + mapperlib._CONFIGURE_MUTEX.release() def _early_mapping(self): self.map() |
