Hi, It seems like configuration is attempted for all new mappers, globally, whenever a query is done. So if library A and B both use sqlalchemy, and A imports B before A's mappers can be properly initialised (e.g. there is a relationship("ClassnameAsString") call somewhere that can't be resolved yet), and B does something to trigger mapper configuration, then it will fail. This occurs even if A and B make separate calls to declarative_base(), even with explicitly different metadata and bound engines.
Here's a boiled-down version of the problem that I've been playing with, which shows that the relationship between Parent and Child is configured when a query on Test is done - even though it may be part of a different library and in a different database: from sqlalchemy import Column, Integer, Text, ForeignKey, create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker, relationship import traceback Base1 = declarative_base() class Test(Base1): __tablename__ = "test" id = Column(Integer, primary_key=True) Base2 = declarative_base() class Parent(Base2): __tablename__ = "parent" id = Column(Integer, primary_key=True) def deferred_parent(): traceback.print_stack() return Parent class Child(Base2): __tablename__ = "child" id_parent = Column(Integer, ForeignKey(Parent.id), primary_key=True) name = Column(Text, primary_key=True) parent = relationship(deferred_parent) engine = create_engine('sqlite://') Session = sessionmaker(bind=engine) session = Session() try: session.query(Test).all() except: pass ...the important bit of the traceback being: File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\session.py", line 1165, in query return self._query_cls(entities, self, **kwargs) File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\query.py", line 108, in __init__ self._set_entities(entities) File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\query.py", line 118, in _set_entities self._set_entity_selectables(self._entities) File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\query.py", line 151, in _set_entity_selectables ent.setup_entity(*d[entity]) File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\query.py", line 2997, in setup_entity self._with_polymorphic = ext_info.with_polymorphic_mappers File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\util\langhelpers.py", line 726, in __get__ obj.__dict__[self.__name__] = result = self.fget(obj) File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\mapper.py", line 1871, in _with_polymorphic_mappers configure_mappers() File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\mapper.py", line 2583, in configure_mappers mapper._post_configure_properties() File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\mapper.py", line 1688, in _post_configure_properties prop.init() File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\interfaces.py", line 144, in init self.do_init() File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\relationships.py", line 1549, in do_init self._process_dependent_arguments() File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\relationships.py", line 1605, in _process_dependent_arguments self.target = self.mapper.mapped_table File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\util\langhelpers.py", line 726, in __get__ obj.__dict__[self.__name__] = result = self.fget(obj) File "R:\sw\external\20150407-0\python27\lib\site-packages\sqlalchemy-0.9.7-py2.7-win32.egg\sqlalchemy\orm\relationships.py", line 1522, in mapper argument = self.argument() File "user!winfis!sqlalchemy!query_triggers_relationship_config.py", line 19, in deferred_parent traceback.print_stack() Is there some method that I've missed of delaying mapper configuration? Aren't the only mappers than need to be set up those that share metadata with entities in the query, or any metadata bound to the engine that will be used? Perhaps configure_mappers() could take an optional metadata/engine and only set up mappers that are related to this? As you can see, I'm doing this with 0.9.7 but looking at the 1.0.0 code I think I'd have the same problem. If it helps, (and you're not already bored) here's our use-case: We have one library that implements a PEP302 import hook, which fetches python code from a database and compiles it. This is managed by sqlalchemy. Some of the code in the database also use sqlalchemy and define other sets of ORM-mapped classes, completely unrelated to the first set, and which relate to tables inreside in completely different databases. If a query needs to be executed to fetch and compile some code while another set of classes are not ready to have their mappers initialised then exceptions are raised. Thanks, Steve. -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.