> > when you say query(Class).filter(<criterion>).one(), that always emits SQL. > It's an open-ended query, and SQLalhcemy doesn't know that s2c1 is the > object which corresponds to the SQL you're about to emit. When the row > comes back, it then extracts the primary key from the incoming row, > determines that identity is already in the identity map and is unexpired, > and the row is skipped >
It ignores new data? I'm clearly going to need to be even more careful about this when I expect 'read committed' behaviour from the database. > (that's the disconnect here - incoming rows are not used if the existing > identity exists and is unexpired). > Is there a global, or per session or something, way to change this ignore-new-data behavior (aside from manually expiring objects prior to querying for data?). Or even more brutal, can the identity map feature be turned off altogether on a per session basis? For those cases when 'read committed' and the associated transaction-transaction contamination is actually the desired behavior, having to manually tell SQLAlchemy to expire everything all the time so that it doesn't ignore new incoming data is quite an extra layer to worry about on top of the the already treacherous concurrency issues around 'read committed'. I always knew the identity map was something to be wary of with concurrency since it is effectively another layer of isolation on top of what the DB is set up to do, but didn't consider the fact that new data that is read would be ignored. >From earlier you said: > If a concurrent transaction were to come in from underneath and change "1" > to "222" while you were still in your ongoing operation, you might be pretty > upset > But I shouldn't be! That is *exactly* how 'read committed' is supposed to behave. If I don't want that, I should be setting "repeatable read" or "serializable". Although I guess it's true that most developers don't quite know about transaction isolation levels (I sure didn't until fairly recently) and might be upset with SQLAlchemy at the first layer, if it did happen to them... if OTOH you had said query(Class).get(pk), that would pull from the identity > map directly and not even hit the DB in this case. > I usually end up using one() and never use get()... I'll look at using get() now, as frequently my one() criteria was only on the PK. And I'll obviously be wary of isolation issues with this. Usually having the identity map is awesome. My main issue was/is that I saw SQL being emitted, was expecting 'read committed' behaviour, and didn't get it. Now I completely know why... thanks again. Russ -- 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/-/98kZ3oQ-jsUJ. To post to this group, send email to sqlalchemy@googlegroups.com. To unsubscribe from this group, send email to sqlalchemy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en.