Esempio n. 1
0
def create_or_verify_database(url, engine_options={}):
    """
    Check that the database is use-able, possibly creating it if empty (this is
    the only time we automatically create tables, otherwise we force the
    user to do it using the management script so they can create backups).

    1) Empty database --> initialize with latest version and return
    2) Database older than migration support --> fail and require manual update
    3) Database at state where migrate support introduced --> add version control information but make no changes (might still require manual update)
    4) Database versioned but out of date --> fail with informative message, user must run "sh manage_db.sh upgrade"

    """
    # Create engine and metadata
    engine = create_engine(url, **engine_options)
    meta = MetaData(bind=engine)
    # Try to load dataset table
    try:
        Table("galaxy_user", meta, autoload=True)
    except NoSuchTableError:
        # No 'galaxy_user' table means a completely uninitialized database, which
        # is fine, init the database in a versioned state
        log.info("No database, initializing")
        # Database might or might not be versioned
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except Exception:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)
        return
    try:
        Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)
    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        exception_msg = "Your database has version '%d' but this code expects version '%d'.  " % (
            db_schema.version, migrate_repository.versions.latest)
        exception_msg += "Back up your database and then migrate the schema by running the following from your Galaxy installation directory:"
        exception_msg += "\n\nsh manage_db.sh upgrade tool_shed\n"
        raise Exception(exception_msg)
    else:
        log.info("At database version %d" % db_schema.version)
Esempio n. 2
0
 def migrate():
     try:
         # Declare the database to be under a repository's version control
         db_schema = schema.ControlledSchema.create(engine, migrate_repository)
     except Exception:
         # The database is already under version control
         db_schema = schema.ControlledSchema(engine, migrate_repository)
     # Apply all scripts to get to current version
     migrate_to_current_version(engine, db_schema)
Esempio n. 3
0
def create_or_verify_database(url, engine_options={}, app=None):
    """
    """
    # Create engine and metadata
    engine = create_engine(url, **engine_options)

    def migrate():
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)

    meta = MetaData(bind=engine)
    if app and getattr(app.config, 'database_auto_migrate', False):
        migrate()
        return

    # Try to load tool_shed_repository table
    try:
        Table("tool_shed_repository", meta, autoload=True)
    except NoSuchTableError:
        # No table means a completely uninitialized database.  If we
        # have an app, we'll set its new_installation setting to True
        # so the tool migration process will be skipped.
        migrate()
        return

    try:
        Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)

    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        exception_msg = "Your database has version '%d' but this code expects version '%d'.  " % (
            db_schema.version, migrate_repository.versions.latest)
        exception_msg += "Back up your database and then migrate the schema by running the following from your Galaxy installation directory:"
        exception_msg += "\n\nsh manage_db.sh upgrade install\n"

    else:
        log.info("At database version %d" % db_schema.version)
Esempio n. 4
0
 def migrate_from_scratch():
     log.info("Creating new database from scratch, skipping migrations")
     current_version = migrate_repository.version().version
     mapping.init(file_path='/tmp',
                  url=url,
                  map_install_models=map_install_models,
                  create_tables=True)
     schema.ControlledSchema.create(engine,
                                    migrate_repository,
                                    version=current_version)
     db_schema = schema.ControlledSchema(engine, migrate_repository)
     assert db_schema.version == current_version
     migrate()
     if app:
         # skips the tool migration process.
         app.new_installation = True
Esempio n. 5
0
def create_or_verify_database(url,
                              galaxy_config_file,
                              engine_options={},
                              app=None):
    """
    Check that the database is use-able, possibly creating it if empty (this is
    the only time we automatically create tables, otherwise we force the
    user to do it using the management script so they can create backups).

    1) Empty database --> initialize with latest version and return
    2) Database older than migration support --> fail and require manual update
    3) Database at state where migrate support introduced --> add version control information but make no changes (might still require manual update)
    4) Database versioned but out of date --> fail with informative message, user must run "sh manage_db.sh upgrade"
    """
    # Create engine and metadata
    engine = create_engine(url, **engine_options)

    def migrate():
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)

    meta = MetaData(bind=engine)
    if app and getattr(app.config, 'database_auto_migrate', False):
        migrate()
        return

    # Try to load dataset table
    try:
        Table("dataset", meta, autoload=True)
    except NoSuchTableError:
        # No 'dataset' table means a completely uninitialized database.  If we have an app, we'll
        # set its new_installation setting to True so the tool migration process will be skipped.
        if app:
            app.new_installation = True
        log.info("No database, initializing")
        migrate()
        return
    try:
        hda_table = Table("history_dataset_association", meta, autoload=True)
    except NoSuchTableError:
        raise Exception(
            "Your database is older than hg revision 1464:c7acaa1bb88f and will need to be updated manually"
        )
    # There is a 'history_dataset_association' table, so we (hopefully) have
    # version 1 of the database, but without the migrate_version table. This
    # happens if the user has a build from right before migration was added.
    # Verify that this is true, if it is any older they'll have to update
    # manually
    if 'copied_from_history_dataset_association_id' not in hda_table.c:
        # The 'copied_from_history_dataset_association_id' column was added in
        # rev 1464:c7acaa1bb88f.  This is the oldest revision we currently do
        # automated versioning for, so stop here
        raise Exception(
            "Your database is older than hg revision 1464:c7acaa1bb88f and will need to be updated manually"
        )
    # At revision 1464:c7acaa1bb88f or greater (database version 1), make sure
    # that the db has version information. This is the trickiest case -- we
    # have a database but no version control, and are assuming it is a certain
    # version. If the user has postion version 1 changes this could cause
    # problems
    try:
        Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)
    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        config_arg = ''
        if galaxy_config_file and os.path.abspath(
                os.path.join(os.getcwd(), 'config',
                             'galaxy.ini')) != galaxy_config_file:
            config_arg = ' -c %s' % galaxy_config_file.replace(
                os.path.abspath(os.getcwd()), '.')
        raise Exception(
            "Your database has version '%d' but this code expects version '%d'.  Please backup your database and then migrate the schema by running 'sh manage_db.sh%s upgrade'."
            % (db_schema.version, migrate_repository.versions.latest,
               config_arg))
    else:
        log.info("At database version %d" % db_schema.version)
Esempio n. 6
0
def create_or_verify_database(url, engine_options={}):
    """
    Check that the database is use-able, possibly creating it if empty (this is
    the only time we automatically create tables, otherwise we force the
    user to do it using the management script so they can create backups).
    
    1) Empty database --> initialize with latest version and return
    2) Database older than migration support --> fail and require manual update
    3) Database at state where migrate support introduced --> add version control information but make no changes (might still require manual update)
    4) Database versioned but out of date --> fail with informative message, user must run "sh manage_db.sh upgrade"
    
    """

    dialect = (url.split(':', 1))[0]
    try:
        egg = dialect_to_egg[dialect]
        try:
            pkg_resources.require(egg)
            log.debug("%s egg successfully loaded for %s dialect" %
                      (egg, dialect))
        except:
            # If the module is in the path elsewhere (i.e. non-egg), it'll still load.
            log.warning(
                "%s egg not found, but an attempt will be made to use %s anyway"
                % (egg, dialect))
    except KeyError:
        # Let this go, it could possibly work with db's we don't support
        log.error(
            "database_connection contains an unknown SQLAlchemy database dialect: %s"
            % dialect)

    # Create engine and metadata
    engine = create_engine(url, **engine_options)
    meta = MetaData(bind=engine)
    # Try to load dataset table
    try:
        dataset_table = Table("dataset", meta, autoload=True)
    except NoSuchTableError:
        # No 'dataset' table means a completely uninitialized database, which
        # is fine, init the database in a versioned state
        log.info("No database, initializing")
        # Database might or might not be versioned
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)
        return
    try:
        hda_table = Table("history_dataset_association", meta, autoload=True)
    except NoSuchTableError:
        raise Exception(
            "Your database is older than hg revision 1464:c7acaa1bb88f and will need to be updated manually"
        )
    # There is a 'history_dataset_association' table, so we (hopefully) have
    # version 1 of the database, but without the migrate_version table. This
    # happens if the user has a build from right before migration was added.
    # Verify that this is true, if it is any older they'll have to update
    # manually
    if 'copied_from_history_dataset_association_id' not in hda_table.c:
        # The 'copied_from_history_dataset_association_id' column was added in
        # rev 1464:c7acaa1bb88f.  This is the oldest revision we currently do
        # automated versioning for, so stop here
        raise Exception(
            "Your database is older than hg revision 1464:c7acaa1bb88f and will need to be updated manually"
        )
    # At revision 1464:c7acaa1bb88f or greater (database version 1), make sure
    # that the db has version information. This is the trickiest case -- we
    # have a database but no version control, and are assuming it is a certain
    # version. If the user has postion version 1 changes this could cause
    # problems
    try:
        version_table = Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            metadata_file_table = Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)
    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        raise Exception(
            "Your database has version '%d' but this code expects version '%d'.  Please backup your database and then migrate the schema by running 'sh manage_db.sh upgrade'."
            % (db_schema.version, migrate_repository.versions.latest))
    else:
        log.info("At database version %d" % db_schema.version)
Esempio n. 7
0
def verify_tools(app, url, galaxy_config_file=None, engine_options={}):
    # Check the value in the migrate_tools.version database table column to verify that the number is in
    # sync with the number of version scripts in ~/lib/galaxy/tools/migrate/versions.
    # Create engine and metadata
    engine = create_engine(url, **engine_options)
    meta = MetaData(bind=engine)
    # The migrate_tools table was created in database version script 0092_add_migrate_tools_table.py.
    Table("migrate_tools", meta, autoload=True)
    # Verify that the code and the database are in sync.
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    latest_tool_migration_script_number = migrate_repository.versions.latest
    if latest_tool_migration_script_number != db_schema.version:
        # The default behavior is that the tool shed is down.
        tool_shed_accessible = False
        if app.new_installation:
            # New installations will not be missing tools, so we don't need to worry about them.
            missing_tool_configs_dict = OrderedDict()
        else:
            tool_panel_configs = common_util.get_non_shed_tool_panel_configs(app)
            if tool_panel_configs:
                # The missing_tool_configs_dict contents are something like:
                # {'emboss_antigenic.xml': [('emboss', '5.0.0', 'package', '\nreadme blah blah blah\n')]}
                tool_shed_accessible, missing_tool_configs_dict = common_util.check_for_missing_tools(app,
                                                                                                      tool_panel_configs,
                                                                                                      latest_tool_migration_script_number)
            else:
                # It doesn't matter if the tool shed is accessible since there are no migrated tools defined in the local Galaxy instance, but
                # we have to set the value of tool_shed_accessible to True so that the value of migrate_tools.version can be correctly set in
                # the database.
                tool_shed_accessible = True
                missing_tool_configs_dict = OrderedDict()
        have_tool_dependencies = False
        for k, v in missing_tool_configs_dict.items():
            if v:
                have_tool_dependencies = True
                break
        if not app.config.running_functional_tests:
            if tool_shed_accessible:
                # Automatically update the value of the migrate_tools.version database table column.
                manage_tools = os.path.abspath(os.path.join(os.path.dirname(__file__), 'scripts', 'manage_tools.py'))
                cmd = [get_executable(), manage_tools, 'upgrade', 'tools']
                if galaxy_config_file:
                    cmd[2:2] = ['-c', galaxy_config_file]
                proc = subprocess.Popen(args=cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
                return_code = proc.wait()
                output = proc.stdout.read(32768)
                if return_code != 0:
                    raise Exception("Error attempting to update the value of migrate_tools.version: %s" % output)
                elif missing_tool_configs_dict:
                    if len(tool_panel_configs) == 1:
                        plural = ''
                        tool_panel_config_file_names = tool_panel_configs[0]
                    else:
                        plural = 's'
                        tool_panel_config_file_names = ', '.join(tool_panel_configs)
                    msg = "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
                    msg += "\n\nThe list of files at the end of this message refers to tools that are configured to load into the tool panel for\n"
                    msg += "this Galaxy instance, but have been removed from the Galaxy distribution.  These tools and their dependencies can be\n"
                    msg += "automatically installed from the Galaxy tool shed at http://toolshed.g2.bx.psu.edu.\n\n"
                    msg += "To skip this process, attempt to start your Galaxy server again (e.g., sh run.sh or whatever you use).  If you do this,\n"
                    msg += "be aware that these tools will no longer be available in your Galaxy tool panel, and entries for each of them should\n"
                    msg += "be removed from your file{} named {}.\n\n".format(plural, tool_panel_config_file_names)
                    msg += "CRITICAL NOTE IF YOU PLAN TO INSTALL\n"
                    msg += "The location in which the tool repositories will be installed is the value of the 'tool_path' attribute in the <tool>\n"
                    msg += 'tag of the file named ./migrated_tool_conf.xml (i.e., <toolbox tool_path="database/shed_tools">).  The default location\n'
                    msg += "setting is 'database/shed_tools', which may be problematic for some cluster environments, so make sure to change it before\n"
                    msg += "you execute the installation process if appropriate.  The configured location must be outside of the Galaxy installation\n"
                    msg += "directory or it must be in a sub-directory protected by a properly configured .hgignore file if the directory is within\n"
                    msg += "the Galaxy installation directory hierarchy.  This is because tool shed repositories will be installed using mercurial's\n"
                    msg += "clone feature, which creates .hg directories and associated mercurial repository files.  Not having .hgignore properly\n"
                    msg += "configured could result in undesired behavior when modifying or updating your local Galaxy instance or the tool shed\n"
                    msg += "repositories if they are in directories that pose conflicts.  See mercurial's .hgignore documentation at the following\n"
                    msg += "URL for details.\n\nhttp://mercurial.selenic.com/wiki/.hgignore\n\n"
                    if have_tool_dependencies:
                        msg += "The following tool dependencies can also optionally be installed (see the option flag in the command below).  If you\n"
                        msg += "choose to install them (recommended), they will be installed within the location specified by the 'tool_dependency_dir'\n"
                        msg += "setting in your main Galaxy configuration file (e.g., uninverse_wsgi.ini).\n"
                        processed_tool_dependencies = []
                        for missing_tool_config, tool_dependencies in missing_tool_configs_dict.items():
                            for tool_dependencies_tup in missing_tool_configs_dict[missing_tool_config]['tool_dependencies']:
                                if tool_dependencies_tup not in processed_tool_dependencies:
                                    msg += "------------------------------------\n"
                                    msg += "Tool Dependency\n"
                                    msg += "------------------------------------\n"
                                    msg += "Name: {}, Version: {}, Type: {}\n".format(tool_dependencies_tup[0],
                                                                                  tool_dependencies_tup[1],
                                                                                  tool_dependencies_tup[2])
                                    if len(tool_dependencies_tup) >= 4:
                                        msg += "Requirements and installation information:\n"
                                        msg += "%s\n" % tool_dependencies_tup[3]
                                    else:
                                        msg += "\n"
                                    msg += "------------------------------------\n"
                                    processed_tool_dependencies.append(tool_dependencies_tup)
                        msg += "\n"
                    msg += "%s" % output.replace('done', '')
                    msg += "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n"
                    msg += "sh ./scripts/migrate_tools/%04d_tools.sh\n" % latest_tool_migration_script_number
                    msg += "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"
                    if have_tool_dependencies:
                        msg += "The tool dependencies listed above will be installed along with the repositories if you add the 'install_dependencies'\n"
                        msg += "option to the above command like this:\n\n"
                        msg += "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n"
                        msg += "sh ./scripts/migrate_tools/%04d_tools.sh install_dependencies\n" % latest_tool_migration_script_number
                        msg += "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"
                        msg += "Tool dependencies can be installed after the repositories have been installed as well.\n\n"
                    msg += "After the installation process finishes, you can start your Galaxy server.  As part of this installation process,\n"
                    msg += "entries for each of the following tool config files will be added to the file named ./migrated_tool_conf.xml, so these\n"
                    msg += "tools will continue to be loaded into your tool panel.  Because of this, existing entries for these tools have been\n"
                    msg += "removed from your file{} named {}.\n\n".format(plural, tool_panel_config_file_names)
                    for missing_tool_config, tool_dependencies in missing_tool_configs_dict.items():
                        msg += "%s\n" % missing_tool_config
                    msg += "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n"
                    raise Exception(msg)
            else:
                log.debug("The main Galaxy tool shed is not currently available, so skipped tool migration %s until next server startup" % db_schema.version)
    else:
        log.info("At migrate_tools version %d" % db_schema.version)
Esempio n. 8
0
def create_or_verify_database(url,
                              galaxy_config_file,
                              engine_options={},
                              app=None,
                              map_install_models=False):
    """
    Check that the database is use-able, possibly creating it if empty (this is
    the only time we automatically create tables, otherwise we force the
    user to do it using the management script so they can create backups).

    1) Empty database --> initialize with latest version and return
    2) Database older than migration support --> fail and require manual update
    3) Database at state where migrate support introduced --> add version control information but make no changes (might still require manual update)
    4) Database versioned but out of date --> fail with informative message, user must run "sh manage_db.sh upgrade"
    """
    # Create the base database if it doesn't yet exist.
    new_database = not database_exists(url)
    if new_database:
        template = app and getattr(app.config, "database_template", None)
        encoding = app and getattr(app.config, "database_encoding", None)
        create_kwds = {}

        message = "Creating database for URI [%s]" % url
        if template:
            message += " from template [%s]" % template
            create_kwds["template"] = template
        if encoding:
            message += " with encoding [%s]" % encoding
            create_kwds["encoding"] = encoding
        log.info(message)
        create_database(url, **create_kwds)

    # Create engine and metadata
    engine = create_engine(url, **engine_options)

    def migrate():
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except Exception:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)

    def migrate_from_scratch():
        if not os.environ.get("GALAXY_TEST_FORCE_DATABASE_MIGRATION"):
            log.info("Creating new database from scratch, skipping migrations")
            current_version = migrate_repository.version().version
            mapping.init(file_path='/tmp',
                         url=url,
                         map_install_models=map_install_models,
                         create_tables=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=current_version)
            db_schema = schema.ControlledSchema(engine, migrate_repository)
            assert db_schema.version == current_version
        migrate()
        if app:
            # skips the tool migration process.
            app.new_installation = True

    meta = MetaData(bind=engine)
    if new_database:
        migrate_from_scratch()
        return
    elif app and getattr(app.config, 'database_auto_migrate', False):
        migrate()
        return

    # Try to load dataset table
    try:
        Table("dataset", meta, autoload=True)
    except NoSuchTableError:
        # No 'dataset' table means a completely uninitialized database.
        log.info("No database, initializing")
        migrate_from_scratch()
        return
    try:
        hda_table = Table("history_dataset_association", meta, autoload=True)
    except NoSuchTableError:
        raise Exception(
            "Your database is older than hg revision 1464:c7acaa1bb88f and will need to be updated manually"
        )
    # There is a 'history_dataset_association' table, so we (hopefully) have
    # version 1 of the database, but without the migrate_version table. This
    # happens if the user has a build from right before migration was added.
    # Verify that this is true, if it is any older they'll have to update
    # manually
    if 'copied_from_history_dataset_association_id' not in hda_table.c:
        # The 'copied_from_history_dataset_association_id' column was added in
        # rev 1464:c7acaa1bb88f.  This is the oldest revision we currently do
        # automated versioning for, so stop here
        raise Exception(
            "Your database is older than hg revision 1464:c7acaa1bb88f and will need to be updated manually"
        )
    # At revision 1464:c7acaa1bb88f or greater (database version 1), make sure
    # that the db has version information. This is the trickiest case -- we
    # have a database but no version control, and are assuming it is a certain
    # version. If the user has postion version 1 changes this could cause
    # problems
    try:
        Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)
    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        config_arg = ''
        if galaxy_config_file and os.path.abspath(
                os.path.join(os.getcwd(), 'config',
                             'galaxy.ini')) != galaxy_config_file:
            config_arg = ' -c %s' % galaxy_config_file.replace(
                os.path.abspath(os.getcwd()), '.')
        expect_msg = "Your database has version '%d' but this code expects version '%d'" % (
            db_schema.version, migrate_repository.versions.latest)
        instructions = ""
        if db_schema.version > migrate_repository.versions.latest:
            instructions = "To downgrade the database schema you have to checkout the Galaxy version that you were running previously. "
            cmd_msg = "sh manage_db.sh%s downgrade %d" % (
                config_arg, migrate_repository.versions.latest)
        else:
            cmd_msg = "sh manage_db.sh%s upgrade" % config_arg
        backup_msg = "Please backup your database and then migrate the database schema by running '%s'." % cmd_msg
        allow_future_database = os.environ.get("GALAXY_ALLOW_FUTURE_DATABASE",
                                               False)
        if db_schema.version > migrate_repository.versions.latest and allow_future_database:
            log.warning(
                "WARNING: Database is from the future, but GALAXY_ALLOW_FUTURE_DATABASE is set, so Galaxy will continue to start."
            )
        else:
            raise Exception("{}. {}{}".format(expect_msg, instructions,
                                              backup_msg))
    else:
        log.info("At database version %d" % db_schema.version)
Esempio n. 9
0
def create_or_verify_database(url, engine_options={}):
    """
    Check that the database is use-able, possibly creating it if empty (this is
    the only time we automatically create tables, otherwise we force the
    user to do it using the management script so they can create backups).
    
    1) Empty database --> initialize with latest version and return
    2) Database older than migration support --> fail and require manual update
    3) Database at state where migrate support introduced --> add version control information but make no changes (might still require manual update)
    4) Database versioned but out of date --> fail with informative message, user must run "sh manage_db.sh upgrade"
    
    """
    dialect = (url.split(':', 1))[0]
    try:
        egg = dialect_to_egg[dialect]
        try:
            pkg_resources.require(egg)
            log.debug("%s egg successfully loaded for %s dialect" %
                      (egg, dialect))
        except:
            # If the module is in the path elsewhere (i.e. non-egg), it'll still load.
            log.warning(
                "%s egg not found, but an attempt will be made to use %s anyway"
                % (egg, dialect))
    except KeyError:
        # Let this go, it could possibly work with db's we don't support
        log.error(
            "database_connection contains an unknown SQLAlchemy database dialect: %s"
            % dialect)
    # Create engine and metadata
    engine = create_engine(url, **engine_options)
    meta = MetaData(bind=engine)
    # Try to load dataset table
    try:
        galaxy_user_table = Table("galaxy_user", meta, autoload=True)
    except NoSuchTableError:
        # No 'galaxy_user' table means a completely uninitialized database, which
        # is fine, init the database in a versioned state
        log.info("No database, initializing")
        # Database might or might not be versioned
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)
        return
    try:
        version_table = Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            metadata_file_table = Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)
    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        exception_msg = "Your database has version '%d' but this code expects version '%d'.  " % (
            db_schema.version, migrate_repository.versions.latest)
        exception_msg += "Back up your database and then migrate the schema by running the following from your Galaxy installation directory:"
        exception_msg += "\n\nsh manage_db.sh upgrade community\n"
        raise Exception(exception_msg)
    else:
        log.info("At database version %d" % db_schema.version)
Esempio n. 10
0
def create_or_verify_database(url, engine_options={}, app=None):
    """
    """
    dialect = (url.split(':', 1))[0]
    try:
        egg = dialect_to_egg[dialect]
        try:
            eggs.require(egg)
            log.debug("%s egg successfully loaded for %s dialect" %
                      (egg, dialect))
        except:
            # If the module is in the path elsewhere (i.e. non-egg), it'll still load.
            log.warning(
                "%s egg not found, but an attempt will be made to use %s anyway"
                % (egg, dialect))
    except KeyError:
        # Let this go, it could possibly work with db's we don't support
        log.error(
            "database_connection contains an unknown SQLAlchemy database dialect: %s"
            % dialect)
    # Create engine and metadata
    engine = create_engine(url, **engine_options)

    def migrate():
        try:
            # Declare the database to be under a repository's version control
            db_schema = schema.ControlledSchema.create(engine,
                                                       migrate_repository)
        except:
            # The database is already under version control
            db_schema = schema.ControlledSchema(engine, migrate_repository)
        # Apply all scripts to get to current version
        migrate_to_current_version(engine, db_schema)

    meta = MetaData(bind=engine)
    if app and getattr(app.config, 'database_auto_migrate', False):
        migrate()
        return

    # Try to load tool_shed_repository table
    try:
        Table("tool_shed_repository", meta, autoload=True)
    except NoSuchTableError:
        # No table means a completely uninitialized database.  If we
        # have an app, we'll set its new_installation setting to True
        # so the tool migration process will be skipped.
        migrate()
        return

    try:
        Table("migrate_version", meta, autoload=True)
    except NoSuchTableError:
        # The database exists but is not yet under migrate version control, so init with version 1
        log.info("Adding version control to existing database")
        try:
            Table("metadata_file", meta, autoload=True)
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=2)
        except NoSuchTableError:
            schema.ControlledSchema.create(engine,
                                           migrate_repository,
                                           version=1)

    # Verify that the code and the DB are in sync
    db_schema = schema.ControlledSchema(engine, migrate_repository)
    if migrate_repository.versions.latest != db_schema.version:
        exception_msg = "Your database has version '%d' but this code expects version '%d'.  " % (
            db_schema.version, migrate_repository.versions.latest)
        exception_msg += "Back up your database and then migrate the schema by running the following from your Galaxy installation directory:"
        exception_msg += "\n\nsh manage_db.sh upgrade install\n"

    else:
        log.info("At database version %d" % db_schema.version)