# HG changeset patch # User Radek Brich # Date 1399480430 -7200 # Node ID fda45bdfd68d4f7611d51ea07b76acd8bc6b68ae # Parent 2a2d0d5df03b6683483c961670e7d81d8f34c976 Update ToolBase: Load cascade of config files, add -c parameter. diff -r 2a2d0d5df03b -r fda45bdfd68d .hgignore --- a/.hgignore Tue May 06 18:37:43 2014 +0200 +++ b/.hgignore Wed May 07 18:33:50 2014 +0200 @@ -2,6 +2,7 @@ ^.project ^.pydevproject ^.settings/org.eclipse.core.resources.prefs +^.idea/ ^pgtoolkit\.conf$ ^doc/_build/ ^build/ diff -r 2a2d0d5df03b -r fda45bdfd68d pgtool --- a/pgtool Tue May 06 18:37:43 2014 +0200 +++ b/pgtool Wed May 07 18:33:50 2014 +0200 @@ -3,7 +3,8 @@ """ Wrapper script for pgtoolkit tools. -Usage: +Usage +----- pgtool --list List all available tools. @@ -17,6 +18,24 @@ pgtool schemadiff --help Get help for tool parameters. +Configuration +------------- + +Global pgtoolkit configuration: + /etc/pgtoolkit.conf + +Local configuration: + ./pgtoolkit.conf + +Additional config file can be loaded using -c parameter (after tool name). + +Configuration from all present files is loaded in above order, +later value overrides previous value. Resulting config file priority is: + + 1) parameter + 2) local + 3) global + """ import pgtoolkit.tools diff -r 2a2d0d5df03b -r fda45bdfd68d pgtoolkit/toolbase.py --- a/pgtoolkit/toolbase.py Tue May 06 18:37:43 2014 +0200 +++ b/pgtoolkit/toolbase.py Wed May 07 18:33:50 2014 +0200 @@ -43,12 +43,21 @@ self.config.add_option('databases', dict) self.config.add_option('meta_db') self.config.add_option('meta_query') - self.parser.add_argument('-Q', dest='queries', action='store_true', + self.parser.add_argument('-Q', dest='show_queries', action='store_true', help='Print database queries.') + self.parser.add_argument('-C', dest='config_file', type=str, + help='Additional config file (besides pgtoolkit.conf).') def load_args(self, args=None, config_file=None): - self.config.load(config_file or 'pgtoolkit.conf') + # Parse command line arguments self.args = self.parser.parse_args(args) + # Load global config + self.config.load('/etc/pgtoolkit.conf', must_exist=False) + # Load local config + self.config.load(config_file or 'pgtoolkit.conf', must_exist=False) + # Load additional config + if self.args.config_file: + self.config.load(self.args.config_file) def init_logging(self): # logging @@ -64,7 +73,7 @@ log_notices.addHandler(handler) log_notices.setLevel(logging.DEBUG) - if self.args.queries: + if self.args.show_queries: log_sql = logging.getLogger('pgmanager_sql') log_sql.addHandler(handler) log_sql.setLevel(logging.DEBUG) @@ -123,11 +132,16 @@ def specify_args(self): ToolBase.specify_args(self) - self.parser.add_argument('target', metavar='target', type=str, help='Target database') + self.config.add_option('target', type=str, default=None) + self.parser.add_argument('target', nargs='?', type=str, help='Target database') + + def load_args(self, args=None, config_file=None): + ToolBase.load_args(self, args, config_file) + self.target = self.args.target or self.config.target or 'default' def setup(self, args=None): ToolBase.setup(self, args) - self.prepare_conns(target=self.args.target) + self.prepare_conns(target=self.target) class SrcDstTool(ToolBase): diff -r 2a2d0d5df03b -r fda45bdfd68d pgtoolkit/tools/loopquery.py --- a/pgtoolkit/tools/loopquery.py Tue May 06 18:37:43 2014 +0200 +++ b/pgtoolkit/tools/loopquery.py Wed May 07 18:33:50 2014 +0200 @@ -1,11 +1,11 @@ -from pgtoolkit.toolbase import ToolBase +from pgtoolkit.toolbase import SimpleTool import logging.handlers import time from datetime import datetime, timedelta -class LoopQueryTool(ToolBase): +class LoopQueryTool(SimpleTool): """ Execute queries in loop, with configurable interval. @@ -13,40 +13,31 @@ """ def __init__(self): - ToolBase.__init__(self, name='loopquery') + SimpleTool.__init__(self, name='loopquery') self.target_isolation_level = 'autocommit' def specify_args(self): - ToolBase.specify_args(self) - self.parser.add_argument('target', nargs='?', metavar='target', type=str, help='Target database') - self.parser.add_argument('-c', dest='config', type=str, help='Additional config file (besides pgtoolkit.conf).') + SimpleTool.specify_args(self) self.parser.add_argument('-q', dest='queries', metavar='QUERY', nargs='*', help='Queries to run.') self.parser.add_argument('--mins', dest='delay_mins', type=int, help='Delay between queries in minutes.') self.parser.add_argument('--secs', dest='delay_secs', type=int, help='Delay between queries in seconds.') - self.config.add_option('target', type=str, default=None) self.config.add_option('queries', type=list, default=[]) self.config.add_option('delay_mins', type=int, default=0) self.config.add_option('delay_secs', type=int, default=0) self.config.add_option('log_path', type=str) def load_args(self, args=None, config_file=None): - ToolBase.load_args(self, args, config_file) - if self.args.config: - self.config.load(self.args.config) + SimpleTool.load_args(self, args, config_file) self.queries = self.args.queries or self.config.queries self.delay_mins = self.args.delay_mins or self.config.delay_mins self.delay_secs = self.args.delay_secs or self.config.delay_secs def init_logging(self): - ToolBase.init_logging(self) + SimpleTool.init_logging(self) if self.config.log_path: self.init_file_logs(self.config.log_path) - def setup(self, args=None): - ToolBase.setup(self, args) - self.prepare_conns(target=self.args.target or self.config.target) - def init_file_logs(self, path): format = logging.Formatter('%(asctime)s %(levelname)-5s %(message)s', '%y-%m-%d %H:%M:%S') handler = logging.handlers.TimedRotatingFileHandler(path+'/main.log', when='midnight', backupCount=5) diff -r 2a2d0d5df03b -r fda45bdfd68d pgtoolkit/tools/runquery.py --- a/pgtoolkit/tools/runquery.py Tue May 06 18:37:43 2014 +0200 +++ b/pgtoolkit/tools/runquery.py Wed May 07 18:33:50 2014 +0200 @@ -1,4 +1,4 @@ -from pgtoolkit.toolbase import ToolBase +from pgtoolkit.toolbase import SimpleTool import logging.handlers import time @@ -13,13 +13,11 @@ """ def __init__(self): - ToolBase.__init__(self, name='runquery') + SimpleTool.__init__(self, name='runquery') self.target_isolation_level = 'autocommit' def specify_args(self): - ToolBase.specify_args(self) - self.parser.add_argument('target', nargs='?', metavar='target', type=str, help='Target database') - self.parser.add_argument('-c', dest='config', type=str, help='Additional config file (besides pgtoolkit.conf).') + SimpleTool.specify_args(self) self.parser.add_argument('-q', dest='queries', metavar='QUERY', nargs='*', help='Queries to run.') self.parser.add_argument('-f', dest='file', metavar='FILE', help='Read query from file.') self.parser.add_argument('--one-query-per-line', action='store_true', help='When reading queries from file, consider each line as separate query.') @@ -28,18 +26,11 @@ self.parser.add_argument('--output-file', dest='output_file', metavar='OUTPUT_FILE', help='Write query result in specified file.') self.parser.add_argument('--format', dest='format', metavar='FORMAT', help='Format string for each line in output file (using Python\'s format()).') - self.config.add_option('target', type=str, default=None) self.config.add_option('queries', type=list, default=[]) self.config.add_option('log_path', type=str) - def setup(self, args=None): - ToolBase.setup(self, args) - self.prepare_conns(target=self.args.target or self.config.target) - def load_args(self, args=None, config_file=None): - ToolBase.load_args(self, args, config_file) - if self.args.config: - self.config.load(self.args.config) + SimpleTool.load_args(self, args, config_file) self.queries = self.args.queries or self.config.queries # read query from file if self.args.file: @@ -73,7 +64,6 @@ def main(self): """Execute the queries.""" - print(self.queries) for q in self.queries: if self.parameters: q = q.format(**self.parameters) diff -r 2a2d0d5df03b -r fda45bdfd68d setup.py --- a/setup.py Tue May 06 18:37:43 2014 +0200 +++ b/setup.py Wed May 07 18:33:50 2014 +0200 @@ -4,7 +4,7 @@ setup( name='pgtoolkit', - version='0.4.0', + version='0.4.1', description='Postgres utilities, build on top of psycopg2', author='Radek Brich', author_email='radek.brich@devl.cz',