migrate.py (3165B)
1 #!/usr/bin/python 2 import os 3 import argparse 4 import logging 5 6 # external imports 7 import alembic 8 from alembic.config import Config as AlembicConfig 9 import confini 10 from xdg.BaseDirectory import ( 11 xdg_data_dirs, 12 load_first_config, 13 ) 14 15 # local imports 16 from chainqueue.db import dsn_from_config 17 18 logging.basicConfig(level=logging.WARNING) 19 logg = logging.getLogger() 20 21 rootdir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 22 dbdir = os.path.join(rootdir, 'chainqueue', 'db') 23 default_migrations_dir = os.path.join(dbdir, 'migrations') 24 default_data_dir = os.path.join(xdg_data_dirs[0], 'chainqueue') 25 26 default_config_dir = load_first_config('chainqueue') 27 config_dir = os.environ.get('CONFINI_DIR', default_config_dir) 28 29 argparser = argparse.ArgumentParser("Database migration tool for chainqueue") 30 argparser.add_argument('-c', type=str, default=config_dir, help='config file') 31 argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') 32 argparser.add_argument('--data-dir', dest='data_dir', type=str, default=default_data_dir, help='data directory') 33 argparser.add_argument('--migrations-dir', dest='migrations_dir', default=default_migrations_dir, type=str, help='path to alembic migrations directory') 34 argparser.add_argument('--reset', action='store_true', help='reset exsting database') 35 argparser.add_argument('-v', action='store_true', help='be verbose') 36 argparser.add_argument('-vv', action='store_true', help='be more verbose') 37 args = argparser.parse_args() 38 39 if args.vv: 40 logging.getLogger().setLevel(logging.DEBUG) 41 elif args.v: 42 logging.getLogger().setLevel(logging.INFO) 43 44 # process config 45 config = confini.Config(args.c, args.env_prefix) 46 config.process() 47 args_override = { 48 'PATH_DATA': getattr(args, 'data_dir'), 49 } 50 config.dict_override(args_override, 'cli args') 51 52 if config.get('DATABASE_ENGINE') == 'sqlite': 53 config.add(os.path.join(config.get('PATH_DATA'), config.get('DATABASE_NAME')), 'DATABASE_NAME', True) 54 55 config.censor('PASSWORD', 'DATABASE') 56 57 config.add(os.path.join(args.migrations_dir, config.get('DATABASE_ENGINE')), '_MIGRATIONS_DIR', True) 58 if not os.path.isdir(config.get('_MIGRATIONS_DIR')): 59 logg.debug('migrations dir for engine {} not found, reverting to default'.format(config.get('DATABASE_ENGINE'))) 60 config.add(os.path.join(args.migrations_dir, 'default'), '_MIGRATIONS_DIR', True) 61 logg.debug('config loaded:\n{}'.format(config)) 62 63 os.makedirs(config.get('PATH_DATA'), exist_ok=True) 64 65 dsn = dsn_from_config(config) 66 67 def main(): 68 logg.info('using migrations dir {}'.format(config.get('_MIGRATIONS_DIR'))) 69 logg.info('using db {}'.format(dsn)) 70 ac = AlembicConfig(os.path.join(config.get('_MIGRATIONS_DIR'), 'alembic.ini')) 71 ac.set_main_option('sqlalchemy.url', dsn) 72 ac.set_main_option('script_location', config.get('_MIGRATIONS_DIR')) 73 74 if args.reset: 75 logg.debug('reset is set, purging existing content') 76 alembic.command.downgrade(ac, 'base') 77 78 alembic.command.upgrade(ac, 'head') 79 80 if __name__ == '__main__': 81 main()