- changed status to wontfix
un-GC'ed / un-configured mappers can be in _mapper_registry
Issue #3664
wontfix
not sure how to detect that these mappers are defunct without just calling gc.collect(), which seems a little heavy handed:
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
atob = Table(
'atob', Base.metadata,
Column('aid', ForeignKey('a.id')),
Column('bid', ForeignKey('b.id'))
)
class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
bs = relationship("B", secondary=lambda: globals().get('atob'))
class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
if True:
del A
del B
del atob
del Base
Base = declarative_base()
class C(Base):
__tablename__ = 'c'
id = Column(Integer, primary_key=True)
configure_mappers()
output:
#!
File "test2.py", line 37, in <module>
configure_mappers()
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 2831, in configure_mappers
mapper._post_configure_properties()
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 1756, in _post_configure_properties
prop.init()
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/interfaces.py", line 183, in init
self.do_init()
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/relationships.py", line 1634, in do_init
self._setup_join_conditions()
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/relationships.py", line 1709, in _setup_join_conditions
can_be_synced_fn=self._columns_are_mapped
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/relationships.py", line 1978, in __init__
self._determine_joins()
File "/home/classic/dev/sqlalchemy/lib/sqlalchemy/orm/relationships.py", line 2082, in _determine_joins
"specify a 'primaryjoin' expression." % self.prop)
sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship A.bs - there are no foreign keys linking these tables.
specifically you'd see this kind of thing if those mappers are part of a module that was garbage collected, like an alembic module.
this patch resolves but gc.collect() doesn't behave the same across Python VMs:
diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py
index 2236b2f..06b2b81 100644
--- a/lib/sqlalchemy/orm/mapper.py
+++ b/lib/sqlalchemy/orm/mapper.py
@@ -2808,6 +2808,9 @@ def configure_mappers():
if not Mapper._new_mappers:
return
+ import gc
+ gc.collect()
+
Mapper.dispatch._for_class(Mapper).before_configured()
# initialize properties on all mappers
# note that _mapper_registry is unordered, which
there's no other indicator on the objects that they're no longer dereferenced since theyre in a cycle.
Comments (1)
-
reporter - Log in to comment
dont see a solution to this, having garbage collection being a side effect of a mapper configure is not appropriate