Lilo wrote: > > My understanding of this query_chooser is that it's used when you want > to execute orm's sql rather than raw sql. > > I don't quite understand what is visit_binary function do from > attribute_shard.py example. What does it mean binary.operator, > binary.left, binary.right.clause and query._criterion? > > The sharding design behind our application is that we have a master > lookup table and shards. What shard to execute sql is based on > querying master lookup table. > > taken from sqlalchemy attribute_shard.py example: > > def query_chooser(query): > ids = [] > > # here we will traverse through the query's criterion, searching > # for SQL constructs. we'll grab continent names as we find them > # and convert to shard ids > class FindContinent(sql.ClauseVisitor): > def visit_binary(self, binary): > if binary.left is weather_locations.c.continent: > if binary.operator == operators.eq: > ids.append(shard_lookup[binary.right.value]) > elif binary.operator == operators.in_op: > for bind in binary.right.clauses: > ids.append(shard_lookup[bind.value]) > > FindContinent().traverse(query._criterion) > if len(ids) == 0: > return ['north_america', 'asia', 'europe', 'south_america'] > else: > return ids > > thank you. >
Hi, (I'm probably going to get the details wrong here, but hopefully the general idea will be right) SQLAlchemy represents SQL expressions as objects, a bit like a parse tree. For example, there are classes that represent tables, joins, functions and so on. It uses a Visitor pattern (http://en.wikipedia.org/wiki/Visitor_pattern) to traverse these structures. A binary clause is an SQL expression with an operator, a left half and a right half. For example, in the clause 'id = 5', binary.left is 'id', binary.right is '5', and binary.operator is '=' (or rather, operators.eq, which is the object that represents '='). The query_chooser function above uses a Visitor to look through all the SQL expressions that make up the query that is about to be executed. Because the only overridden method is 'visit_binary', anything other than binary clauses are ignored. The method body could be written in long-hand as: If the left part of the expression is 'weather_locations.continent': If the expression is 'continent = XXX': add the shard for continent XXX Else if the expression is 'continent IN (XXX, YYY)': add the shards for XXX and YYY (operators.in_op corresponds to the 'IN' operator, and binary.right.clauses contains the right-hand-side of that expression) The fallback case (if len(ids) == 0) happens if the visitor failed to find any expressions that it could handle, in which case all the shards will be queried. I don't understand your situation well enough to know how to adapt the example. If your master lookup table is basically doing the same job as the shard_lookup dictionary in the example, then you could replace shard_lookup above with a function call that does the query. I hope that helps, Simon --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---