add an error if eagerload options etc. are called with no mapper entities

Issue #2069 resolved
Former user created an issue

My Sa version is 0.6.6. Error:

Traceback (most recent call last):
  File "test.py", line 31, in <module>
    session().query(Forum.id, Forum.last_post).options(eagerload('last_post')).all()
  File "/home/florian/.virtualenvs/testing/lib/python2.6/site-packages/sqlalchemy/orm/query.py", line 853, in options
    return self._options(False, *args)
  File "<string>", line 1, in <lambda>
  File "/home/florian/.virtualenvs/testing/lib/python2.6/site-packages/sqlalchemy/orm/query.py", line 52, in generate
    fn(self, *args[1:](1:), **kw)
  File "/home/florian/.virtualenvs/testing/lib/python2.6/site-packages/sqlalchemy/orm/query.py", line 870, in _options
    opt.process_query(self)
  File "/home/florian/.virtualenvs/testing/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py", line 760, in process_query
    self._process(query, True)
  File "/home/florian/.virtualenvs/testing/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py", line 766, in _process
    paths, mappers = self._get_paths(query, raiseerr)
  File "/home/florian/.virtualenvs/testing/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py", line 839, in _get_paths
    path_element = entity.path_entity
AttributeError: '_ColumnEntity' object has no attribute 'path_entity'

See attached test.

Comments (13)

  1. Former user Account Deleted

    Hmm the query isn't really sane; the error makes sense. Why can't I close my ticket gg

  2. Former user Account Deleted

    2069.patch changes two basestring option cases (#5, #7) to behave the same as the PropComparator cases.

    What it still doesn't do in the basestring case, is find the correct _MapperEntity if there is more than one (didn't before either) -- it just returns the first _MapperEntity. I think does work in the PropComparator case, but I didn't try it.

    Below are some cases with the resulting SQL or exceptions.

    Case 1: Just Mapper: basestring
    session.query(Forum).options(eagerload('last_post'))
    SELECT forum.id AS forum_id, forum.name AS forum_name, forum.last_post_id AS forum_last_post_id, post_1.id AS post_1_id, post_1.name AS post_1_name
    FROM forum LEFT OUTER JOIN post AS post_1 ON post_1.id = forum.last_post_id
    
    
    Case 2: Just Mapper: PropComparator
    session.query(Forum).options(eagerload(Forum.last_post))
    SELECT forum.id AS forum_id, forum.name AS forum_name, forum.last_post_id AS forum_last_post_id, post_1.id AS post_1_id, post_1.name AS post_1_name
    FROM forum LEFT OUTER JOIN post AS post_1 ON post_1.id = forum.last_post_id
    
    
    Case 3: Mapper + Column (in that order): basestring
    session.query(Forum, Forum.id).options(eagerload('last_post'))
    SELECT forum.id AS forum_id, forum.name AS forum_name, forum.last_post_id AS forum_last_post_id, post_1.id AS post_1_id, post_1.name AS post_1_name
    FROM forum LEFT OUTER JOIN post AS post_1 ON post_1.id = forum.last_post_id
    
    
    Case 4: Mapper + Column (in that order): PropComparator
    session.query(Forum, Forum.id).options(eagerload(Forum.last_post))
    SELECT forum.id AS forum_id, forum.name AS forum_name, forum.last_post_id AS forum_last_post_id, post_1.id AS post_1_id, post_1.name AS post_1_name
    FROM forum LEFT OUTER JOIN post AS post_1 ON post_1.id = forum.last_post_id
    
    
    Case 5: Column + Mapper (in that order): basestring     <---- was: '_ColumnEntity' object has no attribute 'path_entity'
     session.query(Forum.id, Forum).options(eagerload('last_post'))
    SELECT forum.id AS forum_id, forum.name AS forum_name, forum.last_post_id AS forum_last_post_id, post_1.id AS post_1_id, post_1.name AS post_1_name
    FROM forum LEFT OUTER JOIN post AS post_1 ON post_1.id = forum.last_post_id
    
    
    Case 6: Column + Mapper (in that order): PropComparator
    session.query(Forum.id, Forum).options(eagerload(Forum.last_post))
    SELECT forum.id AS forum_id, forum.name AS forum_name, forum.last_post_id AS forum_last_post_id, post_1.id AS post_1_id, post_1.name AS post_1_name
    FROM forum LEFT OUTER JOIN post AS post_1 ON post_1.id = forum.last_post_id
    
    
    Case 7: Just Column: basestring     <---- was: '_ColumnEntity' object has no attribute 'path_entity'
    session.query(Forum.id).options(eagerload('last_post'))
    Can't find entity last_post in Query.  Current list: ['forum.id']('forum.id')
    
    
    Case 8: Just Column: PropComparator
    session.query(Forum.id).options(eagerload(Forum.last_post))
    Can't find entity Mapper|Forum|forum in Query.  Current list: ['forum.id']('forum.id')
    
  3. Mike Bayer repo owner

    wow - PropertyOption._get_paths() is one of the scariest methods in the ORM, I am impressed. Will try to test tomorrow.

  4. Mike Bayer repo owner
    • changed milestone to 0.7.0

    going to put this in 0.7.0 since the bug is very minor but the change more significant

  5. Mike Bayer repo owner
    • removed status
    • changed status to open

    464835e409dbd607a8a1fbbc8399f6c0c14b3ea8 breaks this test: from #2137

    from sqlalchemy import Integer, Column from sqlalchemy.orm import Session, joinedload from sqlalchemy.ext.declarative import declarative_base

    Base = declarative_base()

    class Foo(Base): tablename = 'foos'

    id = Column(Integer, primary_key=True)
    

    session = Session() session.query(Foo).options(joinedload('not existing one')).statement

  6. Log in to comment