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?
--
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.