On Mar 26, 2013, at 5:24 PM, Laurence Rowe <[email protected]> wrote:

> I'd like to measure the number of database round trips that are associated 
> with a request to my web application so I can write tests to catch potential 
> performance regressions. I've been using mock.Mock(wraps=connection.execute) 
> to keep count and while I think this works for selects, I don't have a good 
> understanding of when executed statements result in serialised network round 
> trips or when they can be 'pipelined', e.g. when inserting new rows.
> 
> So to take a real example, posting to my web app results in the insertion of 
> a row in each of four tables. Afterwards, the connection.execute mock's 
> call_count is 4 and I see 4 INSERTs in my sqlalchemy log:
> 
> INFO:sqlalchemy.engine.base.Engine:INSERT INTO resources (rid) VALUES (?)
> INFO:sqlalchemy.engine.base.Engine:('7745b647ff154ff39cedb897d4e2983c',)
> INFO:sqlalchemy.engine.base.Engine:INSERT INTO statements (rid, predicate, 
> object, tid) VALUES (?, ?, ?, ?)
> INFO:sqlalchemy.engine.base.Engine:('7745b647ff154ff39cedb897d4e2983c', 
> 'organism', '{"scientific_name": "Homo sapiens", "taxon_id": 9606, "_uuid": 
> "7745b647-ff15-4ff3-9ced-b897d4e2983c", "organism_name": "human"}', 
> 'edea69795dd14eb6bed73321cff54471')
> INFO:sqlalchemy.engine.base.Engine:INSERT INTO transactions (tid, data) 
> VALUES (?, ?)
> INFO:sqlalchemy.engine.base.Engine:('edea69795dd14eb6bed73321cff54471', 
> '{"tid": "edea6979-5dd1-4eb6-bed7-3321cff54471", "description": 
> "/organisms/", "user": " remoteuser:TEST"}')
> INFO:sqlalchemy.engine.base.Engine:INSERT INTO current_statements (rid, 
> predicate, sid) VALUES (?, ?, ?)
> INFO:sqlalchemy.engine.base.Engine:('7745b647ff154ff39cedb897d4e2983c', 
> 'organism', 1)
> 
> Is there some way to tell which statements end up having data read from the 
> cursor? Here I have one dependent insert which required the autoincremented 
> primary key from a related row whereas the rest were fully specified.

you can catch SQL traffic more directly using connection events, there are two 
varieties, one catches the high level SQL expression construct, and the other 
catches the activity at the level of cursor.execute() or cursor.executemany() 
(DBAPI cursor).    Intercepting execute/executemany is the most accurate way to 
see all DBAPI interaction fully and exactly as it's being passed:

http://docs.sqlalchemy.org/en/rel_0_8/core/events.html#sqlalchemy.events.ConnectionEvents.before_cursor_execute
http://docs.sqlalchemy.org/en/rel_0_8/core/events.html#sqlalchemy.events.ConnectionEvents.after_cursor_execute

next aspect, if you consider SELECT statements as those which read data from 
the cursor, you can tell if a cursor has results pending on it by checking if 
cursor.description is not None.  You can check for this inside of the 
after_cursor_execute event.   

if you're trying to look at INSERT statements and distinguish between those 
which use an "implicit" autoincrementing primary key and those which have it 
specified, depending on specifics this might be more straightforward at the SQL 
expression level, if you are using table.insert() constructs (or via the ORM 
which also does).    A generic way would be to look at the Table that's the 
subject of the insert, then looking at the parameters to see if parameters 
referring to a full primary key are present.  These values are all present on 
the context passed to the execute events.    Another way that might work more 
expediently, but is a little more of an "inside" method, is to take a look at 
context.inserted_primary_key inside of the after_cursor_execute event; if it 
contains a full primary key without the value None present, that means the 
dialect knew ahead of time the full primary key value (this will only be filled 
in for a single statement execute, not an executemany).

I can work up an example using any combination of these techniques, if you can 
let me know which might seem workable.


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to