Hello, I'm running into some difference in behavior for .exists() in 
SQLAlchemy 1.0.17 and 1.1.11, related to subqueryloads.


class A(db.Model):
    __tablename__ = 'a'

    id = db.Column(db.Integer, primary_key=True)
    b_id = db.Column(db.Integer, db.ForeignKey('b.id'), nullable=False)
    b = db.relationship('B', lazy='subquery')


class B(db.Model):
    __tablename__ = 'b'

    id = db.Column(db.Integer, primary_key=True)


In SQLAlchemy 1.0.17, I can do all of the following:

A.query.exists()  # Note that A.b has lazy='subquery'
A.query.options(subqueryload(A.b)).exists()

# We usually use this in the context of:
db.session.query(A.query.exists()).scalar()

In SQLALchemy 1.1.11, we run into the following error:
A.query.exists()  # Note that A.b has lazy='subquery'

.../lib/python2.7/site-packages/sqlalchemy/orm/query.pyc in exists(self)
   3046         # .with_only_columns() after we have a core select() so that
   3047         # we get just "SELECT 1" without any entities.
-> 3048         return sql.exists(self.add_columns('1').with_labels().
   3049                           statement.with_only_columns([1]))
   3050

.../lib/python2.7/site-packages/sqlalchemy/orm/query.pyc in statement(self)
    465         """
    466
--> 467         stmt = self._compile_context(labels=self._with_labels).\
    468             statement
    469         if self._params:

.../lib/python2.7/site-packages/sqlalchemy/orm/query.pyc in 
_compile_context(self, labels)
   3363
   3364         for entity in self._entities:
-> 3365             entity.setup_context(self, context)
   3366
   3367         for rec in context.create_eager_joins:

.../lib/python2.7/site-packages/sqlalchemy/orm/query.pyc in 
setup_context(self, query, context)
   3725             with_polymorphic=self._with_polymorphic,
   3726             only_load_props=query._only_load_props,
-> 3727             
polymorphic_discriminator=self._polymorphic_discriminator)
   3728
   3729     def __str__(self):

.../lib/python2.7/site-packages/sqlalchemy/orm/loading.pyc in 
_setup_entity_query(context, mapper, query_entity, path, adapter, 
column_collection, with_polymorphic, only_load_props, 
polymorphic_discriminator, **kw)
    257             column_collection=column_collection,
    258             memoized_populators=quick_populators,
--> 259             **kw
    260         )
    261

.../lib/python2.7/site-packages/sqlalchemy/orm/interfaces.pyc in 
setup(self, context, entity, path, adapter, **kwargs)
    515         else:
    516             strat = self.strategy
--> 517         strat.setup_query(context, entity, path, loader, adapter, 
**kwargs)
    518
    519     def create_row_processor(

.../lib/python2.7/site-packages/sqlalchemy/orm/strategies.pyc in 
setup_query(self, context, entity, path, loadopt, adapter, 
column_collection, parentmapper, **kwargs)
    786             orig_query, leftmost_mapper,
    787             leftmost_attr, leftmost_relationship,
--> 788             entity.entity_zero
    789         )
    790

.../lib/python2.7/site-packages/sqlalchemy/orm/strategies.pyc in 
_generate_from_original_query(self, orig_query, leftmost_mapper, 
leftmost_attr, leftmost_relationship, orig_entity)
    859                     ent['entity'] for ent in 
orig_query.column_descriptions
    860                 ])),
--> 861                 False
    862             )
    863

.../lib/python2.7/site-packages/sqlalchemy/orm/query.pyc in 
_set_select_from(self, obj, set_base_alias)
    191
    192         for from_obj in obj:
--> 193             info = inspect(from_obj)
    194             if hasattr(info, 'mapper') and \
    195                     (info.is_mapper or info.is_aliased_class):

.../lib/python2.7/site-packages/sqlalchemy/inspection.pyc in 
inspect(subject, raiseerr)
     73             "No inspection system is "
     74             "available for object of type %s" %
---> 75             type_)
     76     return ret
     77

NoInspectionAvailable: No inspection system is available for object of type 
<type 'NoneType'>


In particular, a subqueried relationship (either through lazy='subquery' or 
subqueryload(A.b)) causes .exists() to fail. We obviously don't call 
subqueryload(A.b) directly with exists queries, but we have models using 
lazy='subquery' that we use .exists() queries for.

My current workaround is A.query.options(lazyload('*')).exists(). Does this 
seem like a bug introduced in 1.1, or were there any intentional changes 
regarding use of .exists() queries?

Thanks!

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to