Thread: [Sqlalchemy-commits] sqlalchemy: - Horizontal shard query places 'shard_id' in
Brought to you by:
zzzeek
From: <co...@sq...> - 2011-01-23 22:03:28
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/8693f8af0b4f changeset: 7288:8693f8af0b4f user: zzzeek date: Sun Jan 23 17:03:19 2011 -0500 description: - Horizontal shard query places 'shard_id' in context.attributes where it's accessible by the "load()" event. [ticket:2031] diffstat: CHANGES | 4 +++ lib/sqlalchemy/ext/horizontal_shard.py | 2 + test/ext/test_horizontal_shard.py | 42 +++++++++++++++++++++++++-------- 3 files changed, 38 insertions(+), 10 deletions(-) diffs (125 lines): diff -r 03a35559d404 -r 8693f8af0b4f CHANGES --- a/CHANGES Fri Jan 21 17:16:47 2011 -0500 +++ b/CHANGES Sun Jan 23 17:03:19 2011 -0500 @@ -87,6 +87,10 @@ - ScopedSession.mapper is removed (deprecated since 0.5). + - Horizontal shard query places 'shard_id' in + context.attributes where it's accessible by the + "load()" event. [ticket:2031] + - sql - LIMIT/OFFSET clauses now use bind parameters [ticket:805] diff -r 03a35559d404 -r 8693f8af0b4f lib/sqlalchemy/ext/horizontal_shard.py --- a/lib/sqlalchemy/ext/horizontal_shard.py Fri Jan 21 17:16:47 2011 -0500 +++ b/lib/sqlalchemy/ext/horizontal_shard.py Sun Jan 23 17:03:19 2011 -0500 @@ -95,6 +95,7 @@ def _execute_and_instances(self, context): if self._shard_id is not None: + context.attributes['shard_id'] = self._shard_id result = self.session.connection( mapper=self._mapper_zero(), shard_id=self._shard_id).execute(context.statement, self._params) @@ -102,6 +103,7 @@ else: partial = [] for shard_id in self.query_chooser(self): + context.attributes['shard_id'] = shard_id result = self.session.connection( mapper=self._mapper_zero(), shard_id=shard_id).execute(context.statement, self._params) diff -r 03a35559d404 -r 8693f8af0b4f test/ext/test_horizontal_shard.py --- a/test/ext/test_horizontal_shard.py Fri Jan 21 17:16:47 2011 -0500 +++ b/test/ext/test_horizontal_shard.py Sun Jan 23 17:03:19 2011 -0500 @@ -1,5 +1,6 @@ import datetime, os from sqlalchemy import * +from sqlalchemy import event from sqlalchemy import sql from sqlalchemy.orm import * from sqlalchemy.ext.horizontal_shard import ShardedSession @@ -11,8 +12,7 @@ # TODO: ShardTest can be turned into a base for further subclasses class ShardTest(TestBase): - @classmethod - def setup_class(cls): + def setUp(self): global db1, db2, db3, db4, weather_locations, weather_reports try: @@ -57,11 +57,12 @@ db1.execute(ids.insert(), nextid=1) - cls.setup_session() - cls.setup_mappers() + self.setup_session() + self.setup_mappers() - @classmethod - def teardown_class(cls): + def tearDown(self): + clear_mappers() + for db in (db1, db2, db3, db4): db.connect().invalidate() for i in range(1,5): @@ -101,8 +102,8 @@ for bind in binary.right.clauses: ids.append(shard_lookup[bind.value]) - - FindContinent().traverse(query._criterion) + if query._criterion is not None: + FindContinent().traverse(query._criterion) if len(ids) == 0: return ['north_america', 'asia', 'europe', 'south_america'] @@ -139,8 +140,7 @@ }) mapper(Report, weather_reports) - - def test_roundtrip(self): + def _fixture_data(self): tokyo = WeatherLocation('Asia', 'Tokyo') newyork = WeatherLocation('North America', 'New York') toronto = WeatherLocation('North America', 'Toronto') @@ -163,6 +163,11 @@ ]: sess.add(c) sess.commit() + return sess + + def test_roundtrip(self): + sess = self._fixture_data() + tokyo = sess.query(WeatherLocation).filter_by(city="Tokyo").one() tokyo.city # reload 'city' attribute on tokyo sess.expunge_all() eq_(db2.execute(weather_locations.select()).fetchall(), [(1, @@ -186,3 +191,20 @@ eq_(set([c.city for c in asia_and_europe]), set(['Tokyo', 'London', 'Dublin'])) + def test_shard_id_event(self): + canary = [] + def load(instance, ctx): + canary.append(ctx.attributes["shard_id"]) + + event.listen(WeatherLocation, "load", load) + sess = self._fixture_data() + + tokyo = sess.query(WeatherLocation).filter_by(city="Tokyo").set_shard("asia").one() + + sess.query(WeatherLocation).all() + eq_( + canary, + ['asia', 'north_america', 'north_america', + 'europe', 'europe', 'south_america', + 'south_america'] + ) \ No newline at end of file |