Mercurial > sqlpython
comparison sqlpyPlus.py @ 151:802d8df993da
midway through making plots saveable
author | catherine@dellzilla |
---|---|
date | Fri, 26 Sep 2008 16:11:29 -0400 |
parents | b00a020b81c6 |
children | c26bc528cb05 |
comparison
equal
deleted
inserted
replaced
150:b00a020b81c6 | 151:802d8df993da |
---|---|
21 or with a python-like shorthand | 21 or with a python-like shorthand |
22 :b = 3 | 22 :b = 3 |
23 | 23 |
24 - catherinedevlin.blogspot.com May 31, 2006 | 24 - catherinedevlin.blogspot.com May 31, 2006 |
25 """ | 25 """ |
26 import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion | 26 import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion, datetime, pickle |
27 from cmd2 import Cmd, make_option, options, Statekeeper | 27 from cmd2 import Cmd, make_option, options, Statekeeper |
28 from output_templates import * | 28 from output_templates import * |
29 try: | |
30 import pylab | |
31 except: | |
32 pass | |
29 | 33 |
30 descQueries = { | 34 descQueries = { |
31 'TABLE': (""" | 35 'TABLE': (""" |
32 atc.column_name, | 36 atc.column_name, |
33 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?", | 37 CASE atc.nullable WHEN 'Y' THEN 'NULL' ELSE 'NOT NULL' END "Null?", |
334 except KeyError: | 338 except KeyError: |
335 if not givenBindVars.has_key(varname): | 339 if not givenBindVars.has_key(varname): |
336 print 'Bind variable %s not defined.' % (varname) | 340 print 'Bind variable %s not defined.' % (varname) |
337 return result | 341 return result |
338 | 342 |
343 try: | |
344 import pylab | |
345 class Plot(object): | |
346 plottable_types = (cx_Oracle.NUMBER, datetime.datetime) | |
347 def __init__(self): | |
348 self.legends = [] | |
349 self.yserieslists = [] | |
350 self.xticks = [] | |
351 def build(self, sqlSession): | |
352 self.title = sqlSession.tblname | |
353 self.xlabel = sqlSession.curs.description[0][0] | |
354 self.datatypes = [d[1] for d in sqlSession.curs.description] | |
355 for (colNum, datatype) in enumerate(self.datatypes): | |
356 if colNum > 0 and datatype in self.plottable_types: | |
357 self.yserieslists.append([row[colNum] for row in sqlSession.rows]) | |
358 self.legends.append(sqlSession.curs.description[colNum][0]) | |
359 if self.datatypes[0] in self.plottable_types: | |
360 self.xvalues = [r[0] for r in sqlSession.rows] | |
361 else: | |
362 self.xvalues = range(sqlSession.curs.rowcount) | |
363 self.xticks = [r[0] for r in sqlSession.rows] | |
364 def save(self): | |
365 pass | |
366 def draw(self): | |
367 if not self.yserieslists: | |
368 result = 'At least one quantitative column needed to plot.' | |
369 return result | |
370 if self.xticks: | |
371 pylab.xticks(self.xvalues, self.xticks) | |
372 for (colName, yseries) in self.yserieslists.items(): | |
373 pylab.plot(xvalues, yseries, '-o') | |
374 pylab.xlabel(self.xlabel) | |
375 pylab.title(self.title) | |
376 pylab.legend(self.legends) | |
377 pylab.show() | |
378 return 'If your lines zigzag, you may want to ORDER BY the x axis.' | |
379 | |
380 except ImportError: | |
381 class Plot(object): | |
382 def build(self, sqlSession): | |
383 pass | |
384 def save(self): | |
385 pass | |
386 def draw(self): | |
387 return 'Must install python-matplotlib to plot query results.' | |
388 | |
339 class sqlpyPlus(sqlpython.sqlpython): | 389 class sqlpyPlus(sqlpython.sqlpython): |
340 defaultExtension = 'sql' | 390 defaultExtension = 'sql' |
341 sqlpython.sqlpython.shortcuts.update({':': 'setbind', '\\': 'psql', '@': '_load'}) | 391 sqlpython.sqlpython.shortcuts.update({':': 'setbind', '\\': 'psql', '@': '_load'}) |
342 multilineCommands = '''select insert update delete tselect | 392 multilineCommands = '''select insert update delete tselect |
343 create drop alter'''.split() | 393 create drop alter'''.split() |
404 for (itm, useq) in zip(row, usequotes)) | 454 for (itm, useq) in zip(row, usequotes)) |
405 result = ['INSERT INTO %s (%s) VALUES (%s);' % | 455 result = ['INSERT INTO %s (%s) VALUES (%s);' % |
406 (self.tblname, ','.join(self.colnames), formatRow(row)) | 456 (self.tblname, ','.join(self.colnames), formatRow(row)) |
407 for row in self.rows] | 457 for row in self.rows] |
408 return '\n'.join(result) | 458 return '\n'.join(result) |
409 | |
410 tableNameFinder = re.compile(r'from\s+([\w$#_"]+)', re.IGNORECASE | re.MULTILINE | re.DOTALL) | 459 tableNameFinder = re.compile(r'from\s+([\w$#_"]+)', re.IGNORECASE | re.MULTILINE | re.DOTALL) |
411 def output(self, outformat, rowlimit): | 460 def output(self, outformat, rowlimit): |
412 self.tblname = self.tableNameFinder.search(self.curs.statement).group(1) | 461 self.tblname = self.tableNameFinder.search(self.curs.statement).group(1) |
413 self.colnames = [d[0] for d in self.curs.description] | 462 self.colnames = [d[0] for d in self.curs.description] |
414 if outformat == '\\i': | 463 if outformat == '\\i': |
439 rname = transpr[x][0] | 488 rname = transpr[x][0] |
440 transpr[x] = map(binascii.b2a_hex, transpr[x]) | 489 transpr[x] = map(binascii.b2a_hex, transpr[x]) |
441 transpr[x][0] = rname | 490 transpr[x][0] = rname |
442 newdesc[0][0] = 'COLUMN NAME' | 491 newdesc[0][0] = 'COLUMN NAME' |
443 result = '\n' + sqlpython.pmatrix(transpr,newdesc) | 492 result = '\n' + sqlpython.pmatrix(transpr,newdesc) |
493 elif outformat == '\\p': | |
494 plot = Plot() | |
495 plot.build(self) | |
496 plot.save() | |
497 return plot.draw() | |
444 else: | 498 else: |
445 result = sqlpython.pmatrix(self.rows, self.curs.description, self.maxfetch) | 499 result = sqlpython.pmatrix(self.rows, self.curs.description, self.maxfetch) |
446 return result | 500 return result |
447 | 501 |
448 legalOracle = re.compile('[a-zA-Z_$#]') | 502 legalOracle = re.compile('[a-zA-Z_$#]') |
449 | 503 |
450 def select_scalar_list(self, sql, binds={}): | 504 def select_scalar_list(self, sql, binds={}): |
451 self.curs.execute(sql, binds) | 505 self.curs.execute(sql, binds) |
452 return [r[0] for r in self.curs.fetchall()] | 506 return [r[0] for r in self.curs.fetchall()] |
493 stmt = "SELECT object_name FROM all_objects WHERE object_name LIKE '%s%%'" | 547 stmt = "SELECT object_name FROM all_objects WHERE object_name LIKE '%s%%'" |
494 completions = self.select_scalar_list(stmt % (text)) | 548 completions = self.select_scalar_list(stmt % (text)) |
495 return completions | 549 return completions |
496 | 550 |
497 rowlimitPattern = pyparsing.Word(pyparsing.nums)('rowlimit') | 551 rowlimitPattern = pyparsing.Word(pyparsing.nums)('rowlimit') |
498 terminatorPattern = (pyparsing.oneOf('; \\s \\S \\c \\C \\t \\x \\h \\g \\G \\i') | 552 terminatorPattern = (pyparsing.oneOf('; \\s \\S \\c \\C \\t \\x \\h \\g \\G \\i \\p') |
499 ^ pyparsing.Literal('\n/') ^ \ | 553 ^ pyparsing.Literal('\n/') ^ \ |
500 (pyparsing.Literal('\nEOF') + pyparsing.stringEnd)) \ | 554 (pyparsing.Literal('\nEOF') + pyparsing.stringEnd)) \ |
501 ('terminator') + \ | 555 ('terminator') + \ |
502 pyparsing.Optional(rowlimitPattern) #+ \ | 556 pyparsing.Optional(rowlimitPattern) #+ \ |
503 #pyparsing.FollowedBy(pyparsing.LineEnd()) | 557 #pyparsing.FollowedBy(pyparsing.LineEnd()) |