From 96534ccf3098937cc003c522bdb9d7b66ea5fda3 Mon Sep 17 00:00:00 2001 From: Dinis Date: Wed, 15 May 2019 20:07:36 +0100 Subject: [PATCH 1/2] First attempt to force migration of the tables even with migrate option set to false. --- gluon/shell.py | 16 +++++++++++++++- gluon/widget.py | 9 ++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/gluon/shell.py b/gluon/shell.py index 89be48dc..89af23fc 100644 --- a/gluon/shell.py +++ b/gluon/shell.py @@ -214,7 +214,8 @@ def run( bpython=False, python_code=None, cronjob=False, - scheduler_job=False): + scheduler_job=False, + force_migrate=False): """ Start interactive shell or run Python script (startfile) in web2py controller environment. appname is formatted like: @@ -244,6 +245,19 @@ def run( os.mkdir(adir) fileutils.create_app(adir) + if force_migrate: + import_models = True + from gluon.dal import DAL + orig_init = DAL.__init__ + + def custom_init(*args, **kwargs): + kwargs['migrate'] = True + logger.info('Forcing migrate=True') + orig_init(*args, **kwargs) + + DAL.__init__ = custom_init + logger.debug('Custom init should not have been called already') + if c: import_models = True extra_request = {} diff --git a/gluon/widget.py b/gluon/widget.py index 218d2816..5e67e176 100644 --- a/gluon/widget.py +++ b/gluon/widget.py @@ -839,6 +839,13 @@ web2py will attempt to run a GUI to ask for it when starting the web server 'collect coverage data when used with --run_system_tests; ' \ 'require Python 2.7+ and the coverage module installed') + parser.add_option('--force_migrate', + default=False, + action='store_true', + help= \ + 'force DAL to migrate all tables that should be migrated when enabled; ' \ + 'monkeypatch in the DAL class to force _migrate_enabled=True') + if '-A' in sys.argv: k = sys.argv.index('-A') elif '--args' in sys.argv: @@ -1037,7 +1044,7 @@ def start(): sys.argv = [options.run] + options.args run(options.shell, plain=options.plain, bpython=options.bpython, import_models=options.import_models, startfile=options.run, - cronjob=options.cronjob) + cronjob=options.cronjob, force_migrate=options.force_migrate) return if options.extcron: From 4455fa48c429cf80e74a4fe35f713d211b6ac8c1 Mon Sep 17 00:00:00 2001 From: Dinis Date: Thu, 16 May 2019 15:33:19 +0100 Subject: [PATCH 2/2] Add a script to force migration of lazy tables and fix missing options in DAL init. --- gluon/shell.py | 13 +++++++++++-- scripts/migrator.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 scripts/migrator.py diff --git a/gluon/shell.py b/gluon/shell.py index 89af23fc..b9bdaeee 100644 --- a/gluon/shell.py +++ b/gluon/shell.py @@ -251,12 +251,12 @@ def run( orig_init = DAL.__init__ def custom_init(*args, **kwargs): + kwargs['migrate_enabled'] = True kwargs['migrate'] = True - logger.info('Forcing migrate=True') + logger.info('Forcing migrate_enabled=True') orig_init(*args, **kwargs) DAL.__init__ = custom_init - logger.debug('Custom init should not have been called already') if c: import_models = True @@ -310,6 +310,15 @@ def run( print(traceback.format_exc()) if import_models: BaseAdapter.close_all_instances('rollback') + elif force_migrate: + try: + execfile("scripts/migrator.py", _env) + if import_models: + BaseAdapter.close_all_instances('commit') + except: + print(traceback.format_exc()) + if import_models: + BaseAdapter.close_all_instances('rollback') else: if not plain: if bpython: diff --git a/scripts/migrator.py b/scripts/migrator.py new file mode 100644 index 00000000..d94c5fa6 --- /dev/null +++ b/scripts/migrator.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +''' +To use, e.g. python .\web2py.py -S APPNAME --force_migrate +''' + +import logging + +logger = logging.getLogger("web2py") + + +def get_databases(request): + dbs = {} + global_env = globals() + for (key, value) in global_env.items(): + try: + cond = isinstance(value, GQLDB) + except: + cond = isinstance(value, SQLDB) + if cond: + dbs[key] = value + return dbs + + +logger.debug('Getting all databases') +databases = get_databases(None) +logger.debug('databases = %s', databases) +for db_name in databases: + logger.debug('Migrating %s', db_name) + db = databases[db_name] + tables = db.tables + for table_name in tables: + # Force migration of lazy tables + logger.debug("Ensuring migration of table '%s'", table_name) + db(db[table_name]).isempty() + db.commit()