""" PythonDBAGraphs: Graphs to help with Oracle Database Tuning Copyright (C) 2016 Robert Taft Durrett (Bobby Durrett) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Contact: bobby@bobbydurrettdba.com db.py Oracle database related code """ import cx_Oracle import sys # Flag to show SQL statements as they are executed or not. # Either N or Y. showsql='N' # Flag to show data returned from queries or not. # Either N or Y. showdata='N' # connection is single connection to database # single open cursor class connection: def __init__(self,username,password,database): """ Login to database and open cursor """ connect_string = username+'/'+password+'@'+database try: self.con = cx_Oracle.connect(connect_string) except cx_Oracle.DatabaseError as e: print("Error logging in: "+str(e.args[0])) print("Username: "+username) print("Database: "+database) sys.exit(-1) self.cur = self.con.cursor() self.column_names=[] def __del__(self): """ Close cursor and connection """ try: self.cur.close() self.con.close() except: return def print_data(self,column_names,data_list): """ Print a nicely formatted version of the data returned by the query. """ # Get the maximum length of each column as a string num_columns = len(column_names) # Initialize lengths to column lengths max_lengths=[] for cn in range(num_columns): max_lengths.append(len(column_names[cn])) # Loop through entire list for d in data_list: for cn in range(num_columns): data_length = len(str(d[cn])) if data_length > max_lengths[cn]: max_lengths[cn] = data_length # Print column names padding for max lengths column_name_header="" for cn in range(num_columns): column_name_header += column_names[cn].rjust(max_lengths[cn]) + " " print(column_name_header) # Print data with same padding for d in data_list: data_line="" for cn in range(num_columns): data_line += str(d[cn]).rjust(max_lengths[cn]) + " " print(data_line) def run_return_all_results(self,query): """ Run the SQL Query and return all of the results. Returns a list of tuples. Each tuple contains one row of query output. """ if showsql == 'Y': print(query) self.cur.execute(query) returned_list = [] for result in self.cur: returned_list.append(result) self.column_names=[] for d in self.cur.description: self.column_names.append(d[0]) if showdata == 'Y': self.print_data(self.column_names,returned_list) return returned_list def get_column_names(self): """ Return a list of the names of the columns returned by the query. """ return self.column_names def run_return_no_results(self,non_query): """ Execute a SQL statement that does not return any results such as DDL, DML. In other words run something that is not a query. """ if showsql == 'Y': print(non_query) self.cur.execute(non_query) return def commit(self): """ Commit all current changes to the database """ self.con.commit() def run_return_flipped_results(self,query): """ Method run_return_all_results returns the query results as a list of tuples. For graphing it can help to have each column's values in a list by itself. So this method returns the query results as a list of lists of column values. r is a list of tuples each tuple is (c1,c2,...) want a list of lists of columns [[c1 c1 c1 ...][c2 c2 c2 ...]...] """ r = self.run_return_all_results(query) if len(r) == 0: return None number_columns = len(r[0]) # create a list of empty lists list_output = [] for i in range(number_columns): list_output.append([]) # append each column to its list for curr_row in r: for i in range(number_columns): list_output[i].append(curr_row[i]) return list_output def run_return_no_results_catch_error(self,non_query): """ Catch error in run_return_no_results """ try: self.run_return_no_results(non_query) except cx_Oracle.DatabaseError: pass return