On Oct 22, 2012, at 11:20 PM, Eric S wrote:

> Firstly, thank you so much for the quick and amazing response, that almost 
> never happens for me.
> 
> I am indeed using a session object per request so this approach looks most 
> appealing:
> 
>           sess.connection().info['my_shard'] = some_shard
> 
> I'm new to sqlalchemy and as such had no idea that you could add arbitrary 
> values to the execution_options/info fields.  
> Where in the docs does it say this?  I only found things such as "autocommit" 
> and "stream_results" shown.
> 
> Also, I guess I'll have to do some research on horizontal_shard, but that 
> looks like it might provide the most sane solution as well.

well for a lot of this we have to rely on API documentation, and possibly API 
docs are looking better in 0.8 than in 0.7.

here's execution options:

        
http://docs.sqlalchemy.org/en/rel_0_7/core/connections.html#sqlalchemy.engine.base.Connection.execution_options

but yes, those docs don't mention that you can really put whatever you want in 
there and pull it from _execution_options, that hasn't been documented as 
public API.   It just seemed like a good solution to your issue as that API is 
pretty stable in any case.  I should probably add a fully public attribute to 
read the current execution options.

and here's info:

        
http://docs.sqlalchemy.org/en/rel_0_7/core/connections.html#sqlalchemy.engine.base.Connection.info

which yeah, doesn't say much.    More detail in this version regarding usage:

        
http://docs.sqlalchemy.org/en/latest/core/connections.html#sqlalchemy.engine.Connection.info




> 
> thanks again,
> eric
> 
> On Monday, October 22, 2012 7:21:26 PM UTC-7, Michael Bayer wrote:
> 
> On Oct 22, 2012, at 10:01 PM, Michael Bayer wrote: 
> 
> > 
> > On Oct 22, 2012, at 9:42 PM, Eric S wrote: 
> > 
> >> Hi everyone, 
> >> 
> >> First some terminology to prevent confusion: 
> >> 
> >>  Database - Mysql database server; currently I have two of them. 
> >> 
> >>  Catalog -    Also typically called databases, but in this situation it is 
> >> the thing created by the database when you issue this command "create 
> >> database foo";  Currently I have 256 of them spread evenly over the 
> >> databases. 
> >> 
> >>  Shard - Lives in my application code and allows me to know in which 
> >> database the catalog is currently living, and helps me create connections 
> >> to it. 
> >> 
> >> My problem is how do I tell the sqlalchemy engines to switch to the 
> >> correct catalog? 
> >> I only want to have one engine per database and share its connection pool. 
> >> 
> >> My current solution is to use a before_execute event which changes the 
> >> catalog.   
> >> This works, but is not great because the catalog isn't passed in, it 
> >> exists "globally", and 
> >> given that my app is multithreaded now I have to use thread local storage 
> >> just to make sure the correct value is used. 
> > 
> > 
> > you can stuff it in the .info dictionary of the Session's existing 
> > connection: 
> > 
> >         sess.connection().info['my_shard'] = some_shard 
> > 
> > lots of ways.  depends on usage. 
> 
> let me just continue, stressing that the idea of 
> connection.execution_options() means you actually get a new Connection object 
> back, which is linked to the original and uses the same DBAPI connection.   
> The ORM's flush procedure can work with this to use a distinct Connection for 
> each individual object instance it flushes. 
> 
> The approach taken in horizontal_shard.py offers some clues how to do this - 
> in that system, a special hook called "connection_callable" is set on the 
> Session, which is significant to the ORM unit of work process when it flushes 
> objects.   This callable is invoked for every mapper/object being flushed, 
> and has the job of returning a Connection that will be used to emit 
> INSERT/UPDATE/DELETE for that object specifically.   You can hook into this 
> callable and return new Connection objects using 
> execution_options(my_shard=some_shard) to produce the new Connection object.  
> I'd probably try storing them in a dictionary-per-shard id so that you aren't 
> creating one Connection object per object being flushed, but that's an 
> optimization - you'd have to make sure they get closed out when the lead 
> connection does. 
> 
> It might also be possible to use horizontal_shard's approach more fully, 
> though poking around a bit it might give you some resistance.    The simplest 
> way would be to provide a new get_bind() method, but that method usually 
> intends to return an Engine object - maybe building a "mock" Engine that will 
> return a Connection with a given shard id applied as an execution_option() 
> would work. 
> 
> 
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To view this discussion on the web visit 
> https://groups.google.com/d/msg/sqlalchemy/-/d-fca69a5pMJ.
> To post to this group, send email to [email protected].
> 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.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
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.

Reply via email to