пятница, 20 октября 2017 г., 20:50:52 UTC+3 пользователь Mike Bayer написал: > > On Fri, Oct 20, 2017 at 11:05 AM, Simon King <si...@simonking.org.uk > <javascript:>> wrote: > > The "is not None" is important when checking a variable that may > > contain a ClauseElement, precisely because ClauseElement defines that > > __bool__ method. > > > > However, in Session.get_bind(), "mapper" is not supposed to contain a > > ClauseElement. It should either be an instance of > > sqlalchemy.orm.mapper.Mapper, or None, in which case "if mapper:" is a > > valid and concise way to write it. Comparing to None might be strictly > > more accurate, but it shouldn't be necessary. > > agree, "mapper" means "mapper" and it is not supposed to be a > ClauseElement. This sounds like arguments are not being passed > correctly somewhere. Would need a demonstration script if something > in SQLAlchemy itself is claimed to be making the mistake. >
Ok, that code produces mentioned error: https://gist.github.com/aCLr/113ac292c05bdb01e964d8e9884d6e5f Traceback (most recent call last): File "/home/anton/Projects/proj/core/run/stuff.py", line 100, in <module> Session.query(with_recursive).set_shard('default').all() File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2654, in all File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2802, in __iter__ File "/home/anton/Projects/proj/core/run/stuff.py", line 28, in _execute_and_instances shard_id=self._shard_id).execute( File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/query.py", line 2806, in _connection_from_session File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/session.py", line 984, in connection File "/home/anton/Projects/proj/core/run/stuff.py", line 40, in get_bind original_bind = super(RoutingSession, self).get_bind(mapper, clause) File "build/bdist.linux-x86_64/egg/sqlalchemy/orm/session.py", line 1336, in get_bind File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/elements.py", line 539, in __bool__ TypeError: Boolean value of this clause is not defined > > > > Simon > > > > > > > > On Fri, Oct 20, 2017 at 3:17 PM, Антонио Антуан <a.ch...@gmail.com > <javascript:>> wrote: > >> Really, `mapper` contains this: <sqlalchemy.sql.selectable.CTE at > >> 0x7fe673fb0a50; group_getter>. But does it changes something? I already > >> encountered this problem in my code, when I checked sqla-objects > existance > >> without "is not None", project was broken. Is it normal to omit that > >> condition in sqlalchemy code? > >> > >> I use: > >>>>> sqlalchemy.__version__ > >> '1.0.19' > >> > >> пятница, 20 октября 2017 г., 16:42:23 UTC+3 пользователь Simon King > написал: > >>> > >>> On Fri, Oct 20, 2017 at 2:15 PM, Антонио Антуан <a.ch...@gmail.com> > wrote: > >>> > Hi. > >>> > I use my own `RoutingSession` and `RoutingQuery` implementation, > most of > >>> > it > >>> > inspired by `sqlalchemy.ext.horizontal_shard`: > >>> > > >>> > class RoutingSession(Session): > >>> > def get_bind(self, mapper=None, clause=None, shard_id=None, > >>> > **kwargs): > >>> > original_bind = None > >>> > try: > >>> > original_bind = super(RoutingSession, > self).get_bind(mapper, > >>> > clause) > >>> > except UnboundExecutionError: > >>> > # may not be bound > >>> > pass > >>> > if shard_id is None: > >>> > shard_id = TenantIDStorage.get_shard_id() # just global > >>> > storage > >>> > bind_for_shard = self.__binds[shard_id] > >>> > if original_bind is not None and original_bind.url == > >>> > bind_for_shard.url: > >>> > return original_bind > >>> > else: > >>> > return bind_for_shard > >>> > > >>> > def __init__(self, shards=None, query_cls=CachingQuery, > >>> > engines_factory=None, **kwargs): > >>> > super(RoutingSession, self).__init__(query_cls=query_cls, > >>> > **kwargs) > >>> > self.__binds = {} > >>> > self.engines_factory = engines_factory > >>> > if shards is not None: > >>> > self.update_shards(**shards) > >>> > > >>> > def _add_bind(self, key, bind): > >>> > self.__binds[key] = bind > >>> > > >>> > > >>> > > >>> > > >>> > class RoutingQuery(Query): > >>> > def __init__(self, *args, **kwargs): > >>> > super(RoutingQuery, self).__init__(*args, **kwargs) > >>> > self._shard_id = TenantIDStorage.get_shard_id() > >>> > > >>> > def get(self, ident): > >>> > self._check_bound_to_shard() > >>> > return super(CachingQuery, self).get(ident) > >>> > > >>> > def _check_bound_to_shard(self): > >>> > if self._shard_id is None: > >>> > raise ValueError('query not bound to any shard') > >>> > > >>> > def _execute_and_instances(self, querycontext): > >>> > self._check_bound_to_shard() > >>> > querycontext.attributes['shard_id'] = self._shard_id > >>> > result = self._connection_from_session( > >>> > mapper=self._mapper_zero(), > >>> > shard_id=self._shard_id).execute( > >>> > querycontext.statement, > >>> > self._params > >>> > ) > >>> > return self.instances(result, querycontext) > >>> > > >>> > > >>> > > >>> > > >>> > > >>> > > >>> > Sometimes I got this error: > >>> > > >>> > File "/home/anton/Projects/proj/admin/proj/admin/views/stats.py", > line > >>> > 898, in _get_filters_from_request > >>> > control_groups = [g.id for g in > >>> > User.get_own_groups_query(current_user.id)] > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/.venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", > > > >>> > line 2802, in __iter__ > >>> > return self._execute_and_instances(context) > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/core/proj/core/orm_extensions/rouing_session.py", > > >>> > line 105, in _execute_and_instances > >>> > shard_id=self._shard_id).execute( > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/.venv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", > > > >>> > line 2806, in _connection_from_session > >>> > **kw) > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", > > > >>> > line 984, in connection > >>> > bind = self.get_bind(mapper, clause=clause, **kw) > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/core/proj/core/orm_extensions/cachingquery.py", > >>> > line 279, in get_bind > >>> > original_bind = super(RoutingSession, self).get_bind(mapper, > clause) > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/.venv/lib/python2.7/site-packages/sqlalchemy/orm/session.py", > > > >>> > line 1336, in get_bind > >>> > if mapper and mapper.mapped_table.bind: > >>> > File > >>> > > >>> > > "/home/anton/Projects/proj/.venv/lib/python2.7/site-packages/sqlalchemy/sql/elements.py", > > > >>> > line 539, in __bool__ > >>> > raise TypeError("Boolean value of this clause is not defined") > >>> > TypeError: Boolean value of this clause is not defined > >>> > > >>> > > >>> > > >>> > > >>> > I found that `mapper` in original `get_bind` always checks with `is > not > >>> > None` condition. There is only one place where condition omitted: > `if > >>> > mapper > >>> > and mapper.mapped_table.bind...`. > >>> > Possibly it is not correct? Or my code does not do something > important? > >>> > >>> Are you able to catch this error in a debugger? > >>> > >>> I'm going to make a wild guess that "mapper" at this point is some > >>> sort of SQL construct (such as a column object or mapped property), > >>> rather than an actual mapper. > >>> > >>> You don't say which version of SQLAlchemy you are using, but since > >>> you've overridden _execute_and_instances, I wonder if you need to use > >>> something like query._bind_mapper() as used by _get_bind_args: > >>> > >>> > >>> < > https://bitbucket.org/zzzeek/sqlalchemy/src/4b22b01ade6f94cc4db2f2040c802067a25d29a4/lib/sqlalchemy/orm/query.py?at=rel_1_1_14&fileviewer=file-view-default#query.py-2872> > > > >>> > >>> Hope that helps, > >>> > >>> Simon > >> > >> -- > >> 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+...@googlegroups.com <javascript:>. > >> To post to this group, send email to sqlal...@googlegroups.com > <javascript:>. > >> Visit this group at https://groups.google.com/group/sqlalchemy. > >> For more options, visit https://groups.google.com/d/optout. > > > > -- > > 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+...@googlegroups.com <javascript:>. > > To post to this group, send email to sqlal...@googlegroups.com > <javascript:>. > > Visit this group at https://groups.google.com/group/sqlalchemy. > > For more options, visit https://groups.google.com/d/optout. > -- 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.