Russell Keith-Magee wrote:

> Interesting idea! Thanks for sharing.

http://www.oreillynet.com/ruby/blog/2008/01/assert_efficient_sql.html

> I've just spent a bunch of time hunting down a performance regression
> that was caused by someone tweaking a database index, so I'd love to
> see something like this in trunk.

Thanks for having 1 point more enthusiasm than me! The assertion only
works for MySQL (or anything with a similar EXPLAIN result), and all
TDD tests "should" run in SQLite3, for speed. (At my day gig I really
ought to get off my lazy butt and configure our integration test
server to run in MySQL instead of SQLite3, and then any MySQL-specific
tests would run inside if statements. The closer to the production
environment the better.)

> A couple of quick comments:
>
>  * You're using str(qs.query) to get the contents of the query. This
> will work fine when you are only using a single database, but in the
> general case, you should be using
> qs.query.get_compiler(qs.db).as_sql(). This will ensure that the SQL
> that is EXPLAINed is exactly the same as the query that is issued,
> including database specific modifications.

Ah, that's why I asked that in the prequel post, then gave up the
instant I discovered qs.query. And you are indeed correct, because,
for example, a harmless-looking filter like .filter(status='P') was
coming out SELECT ... status = P, without quotes on the P. I was about
to ask about that; tx for the answer.

>  * An assertion named "performant" will get into trunk over my cold,
> dead body :-) People: performant is not a word. Or, at least, it is,
> but not one that means what you think it means.

Ah, hence the word is free for anyone to use on any code that won't be
submitting to the trunk - thanks! And the pseudo-word "Performant"
fits into a dead-spot where there's no other word, so we are back to
the classic dispute between the Prescriptive and the Descriptive
dictionary. Swell.

(Inside joke: "Swell" was formerly proscribed...)

More importantly, the assertion does _not_ check we are perform...ance-
oriented, it checks we are _compliant_ to some DBA standard.
Performance checks are for soak tests. So try this:

  query, report = self.assert_explain_sql( qs,
mysql=dict(index='frob'),
 
sqlite=dict(whatever='42'),
 
bamboozql=dict(without='ALL') )

  self.assert_contains('ORDER BY foot_size', query)

Now gaze in awe at that last assertion. If we wanted to test that we
have a correct .order() builder, we might write a test that pushes
records out-of-order, then queries the database and checks the records
are in the right order. That kind of test smacks of brute-force, and
the database might accidentally fool the test, and put the records
into order for some other reason.

Because we are really testing if our calls to the QuerySet builder
were correct, we will pin down their behavior if we parse back the
intermediate value - the actual SELECT statement, and then interrogate
it.

Oh, yeah, and such a test is also perform...ing. Well. Because it
doesn't build records or read them.

I will see when I have time to code that up...

--
  Phlip
  http://c2.com/cgi/wiki?MoreliaViridis

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to