With a few minutes of typing and looking stuff up (e.g., how to define compound keys for an already extant schema/db), I was up and running and was able to concentrate fully on the problem at hand (reports) and how to represent data visually (matplotlib). Now that's how an ORM is supposed to work :-)
Here are the schemas I defined in python:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Revision(object): | |
""" | |
A storm ORM object representing a row in the trac 'revsion' SQLite table. | |
""" | |
__storm_table__ = 'revision' | |
rev = Unicode(primary=True) | |
time = Int() | |
author = Unicode() | |
message = Unicode() | |
def getDateTime(self): | |
try: | |
self.dt | |
except AttributeError: | |
self.dt = convertEpoch2DT(self.time) | |
return self.dt | |
class NodeChange(object): | |
""" | |
A storm ORM object representing a row in the trac 'node_change' SQLite | |
table. | |
""" | |
__storm_table__ = 'node_change' | |
__storm_primary__ = ('rev', 'path', 'change_type') | |
rev = Unicode() | |
path = Unicode() | |
node_type = Unicode() | |
change_type = Unicode() | |
base_path = Unicode() | |
base_rev = Unicode() | |
Revision.nodeChanges = ReferenceSet(Revision.rev, NodeChange.rev) | |
class TicketChange(object): | |
""" | |
A storm ORM object representing a row in the trac 'ticket_change' SQLite | |
table. | |
""" | |
__storm_table__ = 'ticket_change' | |
__storm_primary__ = ('ticket', 'time', 'field') | |
ticket = Unicode() | |
time = Int() | |
author = Unicode() | |
field = Unicode() | |
oldvalue = Unicode() | |
newvalue = Unicode() |
Note the 1-to-m relationship of revision to nodes changed -- so easy :-)
This is exactly what a (good) tool is supposed to let you do: focus on and solve the larger problem at hand, not get lost fixing tools. With the schemas defined, the queries took literal seconds to write, I had my data, and was able to start generating textual summaries as well as processing the queries for graphs.
Wanna see some graphs? Below is a slide show of some graphs (just a few of the hundreds that are generated) representing the work of the Divmod dev team over various points in time on a secondary trac instance (not our main, Divmod trac instance). Though I haven't included them in the slide show, the code also generates graphs per-user, per-time-period.
Created with Admarket's flickrSLiDR.
Update: Thanks Nafai for poking me about the oversight of not giving shouts out for the graphing tool: matplotlib (of which I have been a huge fan of since I first heard about it years ago, having suffered through proprietary and kludgey Matlab as a physics student).