def handle(self, **options): if options.pop("interactive") and self._cancel_reset(): return for db, dbconf in six.iteritems(settings.DATABASES): logger.info("Selecting DROP TABLE Statement for the engine...") dt_stmt = self._drop_table_stmt(dbconf) logger.info("Retrieving Existing Tables...") tables = self._get_tables(db) logger.info("Dropping Tables...") self._drop_tables(tables, db, dt_stmt) logger.info("Creating Database '{}'...".format(db)) # Hack so that migrate can't find migrations files # this way, syncdb will be run instead of migrate. # This is preferable because # users who are used to running "otree resetdb" # may not know how to run 'otree makemigrations'. # This means their migration files will not be up to date, # ergo migrate will create tables with an outdated schema. # after the majority of oTree users have this new version # of resetdb, we can add a migrations/ folder to each app # in the sample games and the app template, # and deprecate resetdb # and instead use "otree makemigrations" and "otree migrate". # also, syncdb is faster than migrate, and there is no advantage # to migrate since it's being run on a newly created DB anyway. # patch .migrations_module() to return a nonexistent module, # instead of app_name.migrations. # because this module is not found, # migration system will assume the app has no migrations, # and run syncdb instead. with mock.patch.object( MigrationLoader, 'migrations_module', return_value='migrations nonexistent hack' ): # note: In 1.9, will need to pass --run-syncdb flag call_command( 'migrate', database=db, interactive=False, **options) # second call to 'migrate', simply to # fake migrations so that runserver doesn't complain # about unapplied migrations call_command( 'migrate', database=db, fake=True, interactive=False, **options) project_root = getattr(settings, 'BASE_DIR', None) if project_root: add_empty_migrations_to_all_apps(project_root)
def handle(self, **options): if options.pop("interactive") and not self._confirm(): self.stdout.write('Canceled.') return for db, dbconf in six.iteritems(settings.DATABASES): db_engine = dbconf['ENGINE'] if 'postgresql' in db_engine.lower(): db_engine = 'PostgreSQL' elif 'sqlite' in db_engine.lower(): db_engine = 'SQLite' elif 'mysql' in db_engine.lower(): db_engine = 'MySQL' logger.info("Database engine: {}".format(db_engine)) dt_stmt = self._drop_table_stmt(dbconf) logger.info("Retrieving Existing Tables...") tables = self._get_tables(db) logger.info("Dropping Tables...") # use a transaction to prevent the DB from getting in an erroneous # state, which can result in a different error message when resetdb # is run again, making the original error hard to trace. with transaction.atomic( using=connections[db].alias, savepoint=connections[db].features.can_rollback_ddl ): self._drop_tables(tables, db, dt_stmt) logger.info("Creating Database '{}'...".format(db)) self.syncdb(db, options) # second call to 'migrate', simply to # fake migrations so that runserver doesn't complain # about unapplied migrations # note: In 1.9, will need to pass --run-syncdb flag call_command( 'migrate', database=db, fake=True, interactive=False, **options) project_root = getattr(settings, 'BASE_DIR', None) if project_root: add_empty_migrations_to_all_apps(project_root)
def modify_project_files(self, options): project_name, target = options['name'], options['directory'] if target is None: project_root_dir = os.path.join(os.getcwd(), project_name) else: project_root_dir = os.path.abspath(os.path.expanduser(target)) imp = platform.python_implementation() implementation_name = IMPLEMENTATIONS_ALIAS.get(imp, imp).lower() version = ".".join(map(str, sys.version_info[:3])) runtime_string = "{}-{}\n".format(implementation_name, version) runtime_path = os.path.join(project_root_dir, "runtime.txt") with open(runtime_path, "w") as fp: fp.write(runtime_string) # overwrite Procfile with new channels/asgi one procfile_path = os.path.join(self.core_project_template_path, 'Procfile') shutil.copy(procfile_path, project_root_dir) add_empty_migrations_to_all_apps(project_root_dir)
def modify_project_files(self, options): project_name, target = options['name'], options['directory'] if target is None: project_root_dir = os.path.join(os.getcwd(), project_name) else: project_root_dir = os.path.abspath(os.path.expanduser(target)) imp = platform.python_implementation() implementation_name = IMPLEMENTATIONS_ALIAS.get(imp, imp).lower() version = ".".join(map(str, sys.version_info[:3])) runtime_string = "{}-{}\n".format(implementation_name, version) runtime_path = os.path.join(project_root_dir, "runtime.txt") with open(runtime_path, "w") as fp: fp.write(runtime_string) # overwrite Procfile with new channels/asgi one procfile_path = os.path.join( self.core_project_template_path, 'Procfile') shutil.copy(procfile_path, project_root_dir) add_empty_migrations_to_all_apps(project_root_dir)