pgtoolkit/tools/listserial.py
author Radek Brich <brich.radek@ifortuna.cz>
Tue, 06 May 2014 18:37:43 +0200
changeset 101 2a2d0d5df03b
parent 93 listserial.py@b72591087495
permissions -rw-r--r--
Refactor ToolBase to allow tool composition. Add TableSync tool (composited). Move more tools under pgtool.

from pgtoolkit.toolbase import SimpleTool
from pgtoolkit import pgbrowser
from pycolib.ansicolor import highlight, WHITE, YELLOW, RED, BOLD


class ListSerialTool(SimpleTool):

    """List sequences near to overflow.

    Checks all sequences attached to a column of type integer.

    Highlight dangerous values of sequence:
    * Yellow - near overflow (90%)
    * Red - already over...

    Does not list sequences with value under 50% of range.

    """

    max_int = 2147483647

    def __init__(self):
        SimpleTool.__init__(self, name='listserial')

    def main(self):
        conn = self.pgm.get_conn('target')
        browser = pgbrowser.PgBrowser(conn)
        rows = browser.list_sequences()
        sequences = []
        for row in rows:
            if row['related_column_type'] == 'integer':
                # read sequence attributes like last_value
                q = 'SELECT * FROM "%s"."%s"' % (row['sequence_schema'], row['sequence_name'])
                curs = conn.cursor()
                curs.execute(q)
                attrs = curs.fetchone_dict()
                # skip this sequence if its cycled and has safe max_value
                if attrs['is_cycled'] and attrs['max_value'] <= self.max_int:
                    continue
                # skip sequences with last_value not yet in half of max_int
                if attrs['last_value'] < self.max_int / 2:
                    continue
                # remember rest of sequences
                row['attrs'] = attrs
                sequences.append(row)
        # sort most dangerous on top
        sequences.sort(key=lambda x: x['attrs']['last_value'], reverse=True)
        # print out what we've found
        for seq in sequences:
            print('Sequence:', seq['sequence_schema'] + '.' + seq['sequence_name'])
            print(' Related:', seq['sequence_schema'] + '.' + seq['related_table'], seq['related_column'], '(' + seq['related_column_type'] + ')')
            print('  integer max', '2147483647')
            # colorize last value
            last_val = seq['attrs']['last_value']
            col = WHITE + BOLD
            if last_val > self.max_int * 0.9:
                # near max
                col = YELLOW + BOLD
            if last_val > self.max_int:
                # over max
                col = RED + BOLD
            print('   last_value', highlight(1, col) + str(last_val) + highlight(0))
            for key in ('min_value', 'max_value', 'is_cycled'):
                print('   ', key, seq['attrs'][key])
            print()


cls = ListSerialTool