# HG changeset patch # User catherine@bothari # Date 1256946323 14400 # Node ID 3a2db0db302f44a8157ed60825656bb0d7fa8a56 # Parent c42d9619e715a5b8d55709306aca7265408b9188 must synch diff -r c42d9619e715 -r 3a2db0db302f setup.py --- a/setup.py Fri Oct 16 18:11:08 2009 -0400 +++ b/setup.py Fri Oct 30 19:45:23 2009 -0400 @@ -17,8 +17,12 @@ url="http://packages.python.org/sqlpython", packages=find_packages(), include_package_data=True, - install_requires=['pyparsing','cmd2>=0.5.6','cx_Oracle>=5.0.2', + install_requires=['pyparsing','cmd2>=0.5.6', 'genshi>=0.5','sqlalchemy'], + extras_require = { + 'oracle': ['cx_Oracle>=5.0.2'], + 'postgres': ['psycopg2'], + }, keywords = 'client oracle database', license = 'MIT', platforms = ['any'], diff -r c42d9619e715 -r 3a2db0db302f sqlpython/mysqlpy.py --- a/sqlpython/mysqlpy.py Fri Oct 16 18:11:08 2009 -0400 +++ b/sqlpython/mysqlpy.py Fri Oct 30 19:45:23 2009 -0400 @@ -163,18 +163,19 @@ except Exception, e: self.perror(e) - def do_sessinfo(self,args): - '''Reports session info for the given sid, extended to RAC with gv$''' - try: - if not args: - self.curs.execute('SELECT sid FROM v$mystat') - args = self.curs.fetchone()[0] - self.onecmd('SELECT * from gv$session where sid=%s\\t' % args) - except cx_Oracle.DatabaseError, e: - if 'table or view does not exist' in str(e): - self.perror('This account has not been granted SELECT privileges to v$mystat or gv$session.') - else: - raise + if cx_Oracle: + def do_sessinfo(self,args): + '''Reports session info for the given sid, extended to RAC with gv$''' + try: + if not args: + self.curs.execute('SELECT sid FROM v$mystat') + args = self.curs.fetchone()[0] + self.onecmd('SELECT * from gv$session where sid=%s\\t' % args) + except cx_Oracle.DatabaseError, e: + if 'table or view does not exist' in str(e): + self.perror('This account has not been granted SELECT privileges to v$mystat or gv$session.') + else: + raise def do_sleect(self,args): '''implements sleect = select, a common typo''' diff -r c42d9619e715 -r 3a2db0db302f sqlpython/plothandler.py --- a/sqlpython/plothandler.py Fri Oct 16 18:11:08 2009 -0400 +++ b/sqlpython/plothandler.py Fri Oct 30 19:45:23 2009 -0400 @@ -1,10 +1,12 @@ -import shelve, pickle, cx_Oracle, datetime, sys, itertools +import shelve, pickle, datetime, sys, itertools +from sqlpython import cx_Oracle shelvename = 'plot.shelve' try: import pylab class Plot(object): - plottable_types = (cx_Oracle.NUMBER, datetime.datetime) + plottable_types = (cx_Oracle and cx_Oracle.NUMBER, datetime.datetime) + #TODO: add non-Oracle types def __init__(self): self.legends = [] self.yserieslists = [] diff -r c42d9619e715 -r 3a2db0db302f sqlpython/sqlpyPlus.py --- a/sqlpython/sqlpyPlus.py Fri Oct 16 18:11:08 2009 -0400 +++ b/sqlpython/sqlpyPlus.py Fri Oct 30 19:45:23 2009 -0400 @@ -23,7 +23,7 @@ - catherinedevlin.blogspot.com May 31, 2006 """ -import sys, os, re, sqlpython, cx_Oracle, pyparsing, re, completion +import sys, os, re, sqlpython, pyparsing, re, completion import datetime, pickle, binascii, subprocess, time, itertools, hashlib import traceback, operator from cmd2 import Cmd, make_option, options, Statekeeper, Cmd2TestCase @@ -31,7 +31,7 @@ from schemagroup import MetaData from metadata import metaqueries from plothandler import Plot -from sqlpython import Parser +from sqlpython import Parser, cx_Oracle, psycopg2 import imagedetect import warnings warnings.filterwarnings('ignore', 'BaseException.message', DeprecationWarning) @@ -412,7 +412,7 @@ def dbms_output(self): "Dumps contents of Oracle's DBMS_OUTPUT buffer (where PUT_LINE goes)" try: - line = self.curs.var(cx_Oracle.STRING) + line = self.curs.var(cx_Oracle.STRING) # TODO: would regular string and number work? status = self.curs.var(cx_Oracle.NUMBER) self.curs.callproc('dbms_output.get_line', [line, status]) while not status.getvalue(): @@ -752,7 +752,8 @@ self.rows = self.curs.fetchmany(min(self.maxfetch, (rowlimit or self.maxfetch))) self.colnames = [d[0] for d in self.curs.description] self.coltypes = [d[1] for d in self.curs.description] - if cx_Oracle.BLOB in self.coltypes: + #TODO: Other databases can have BLOBs, too + if cx_Oracle and (cx_Oracle.BLOB in self.coltypes): self.rows = [ [( (coltype == cx_Oracle.BLOB) and BlobDisplayer(datum, (rownum < self.bloblimit))) @@ -833,7 +834,7 @@ self.poutput(txt) if opts.full: - # Hmm... dependent objects... + # TODO: 'full' option for gerald metadata if opts.full: for dependent_type in ('OBJECT_GRANT', 'CONSTRAINT', 'TRIGGER'): @@ -986,10 +987,13 @@ self.poutput('%d: %s' % (line_num, line)) def _col_type_descriptor(self, col): - if 'precision' in col: - return '%s(%d,%d)' % (col['type'], col['length'], col['precision']) - elif 'length' in col: - return '%s(%d)' % (col['type'], col['length']) + #if col['type'] in ('integer',): + # return col['type'] + if ('length' in col) and (col['length'] is not None): + if ('precision' in col) and (col['precision'] is not None): + return '%s(%d,%d)' % (col['type'], col['length'], col['precision']) + else: + return '%s(%d)' % (col['type'], col['length']) else: return col['type'] @@ -997,6 +1001,7 @@ columns = [c['columns'] for c in tbl.constraints.values() if c['type'] == type] if columns: return reduce(list.extend, columns) + #TODO: in postgres, _key_columns returns 'fishies_pkey' instead of 'n' else: return [] @@ -1050,23 +1055,23 @@ def do_deps(self, arg): '''Lists all objects that are dependent upon the object.''' #TODO: Can this be Geraldized? - target = arg.upper() - object_type, owner, object_name = self.resolve(target) - if object_type == 'PACKAGE BODY': - q = "and (type != 'PACKAGE BODY' or name != :object_name)'" - object_type = 'PACKAGE' - else: - q = "" - q = """SELECT name, - type - from user_dependencies - where - referenced_name like :object_name - and referenced_type like :object_type - and referenced_owner like :owner - %s;""" % (q) - self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix), - bindVarsIn={'object_name':object_name, 'object_type':object_type, 'owner':owner}) + for obj in self._matching_database_objects(arg, opts): + + if object_type == 'PACKAGE BODY': + q = "and (type != 'PACKAGE BODY' or name != :object_name)'" + object_type = 'PACKAGE' + else: + q = "" + q = """SELECT name, + type + from user_dependencies + where + referenced_name like :object_name + and referenced_type like :object_type + and referenced_owner like :owner + %s;""" % (q) + self.do_select(self.parsed(q, terminator=arg.parsed.terminator or ';', suffix=arg.parsed.suffix), + bindVarsIn={'object_name':object_name, 'object_type':object_type, 'owner':owner}) @options([all_users_option]) def do_comments(self, arg, opts): @@ -1274,8 +1279,7 @@ @options(standard_options) def do__dir_constraints(self, arg, opts): ''' - Called with an exact table name, lists the indexes of that table. - Otherwise, acts as shortcut for `ls index/*(arg)*` + Lists constaints of a table. ''' self.do__dir_(arg, opts, 'constraints', self._str_constraint) @@ -1369,7 +1373,7 @@ sql = 'SELECT %s' self.curs.execute(sql % val) return True, var, self.curs.fetchone()[0] - except: # should not be bare - should catch cx_Oracle.DatabaseError, etc. + except: # TODO: should not be bare - should catch cx_Oracle.DatabaseError, etc. return True, var, val # we give up and assume it's a string def do_setbind(self, arg): @@ -1492,7 +1496,11 @@ def metadata(self): schemas = self.connections[self.connection_number]['schemas'] - username = self.connections[self.connection_number]['user'].upper() + username = self.connections[self.connection_number]['user'] + if self.rdbms == 'oracle': + username = username.upper() + elif self.rdbms == 'postgres': + username = username.lower() return (username, schemas) def _to_sql_wildcards(self, original): @@ -1550,7 +1558,7 @@ self.pfeedback('Results are incomplete - only %d schemas mapped so far' % schemas.complete) seek = self._regex(arg, opts.get('exact')) - qualified = opts.get('all') + qualified = opts.get('all') or '.' in arg # TODO: is this working? for (schema_name, schema) in schemas.items(): if schema_name == username or opts.get('all'): for (name, dbobj) in schema.schema.items(): diff -r c42d9619e715 -r 3a2db0db302f sqlpython/sqlpython.py --- a/sqlpython/sqlpython.py Fri Oct 16 18:11:08 2009 -0400 +++ b/sqlpython/sqlpython.py Fri Oct 30 19:45:23 2009 -0400 @@ -8,9 +8,17 @@ # Best used with the companion modules sqlpyPlus and mysqlpy # See also http://twiki.cern.ch/twiki/bin/view/PSSGroup/SqlPython -import cmd2,getpass,binascii,cx_Oracle,re,os,platform +import cmd2,getpass,binascii,re,os,platform import sqlalchemy, pyparsing, schemagroup __version__ = '1.6.8' +try: + import cx_Oracle +except ImportError: + cx_Oracle = None +try: + import psycopg2 +except ImportError: + psycopg2 = None class Parser(object): comment_def = "--" + pyparsing.NotAny('-' + pyparsing.CaselessKeyword('begin')) + pyparsing.ZeroOrMore(pyparsing.CharsNotIn("\n"))