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)
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)
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
# 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:
db1.execute(ids.insert(), nextid=1)
- cls.setup_session()
- cls.setup_mappers()
+ self.setup_session()
+ self.setup_mappers()
+
+ def tearDown(self):
+ clear_mappers()
- @classmethod
- def teardown_class(cls):
for db in (db1, db2, db3, db4):
db.connect().invalidate()
for i in range(1,5):
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']
})
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')
]:
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,
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