示例#1
0
def test_validate_schema(threedi_db):
    """Validate a correct schema version"""
    schema = ModelSchema(threedi_db)
    with mock.patch.object(schema,
                           "get_version",
                           return_value=constants.MIN_SCHEMA_VERSION):
        assert schema.validate_schema()
示例#2
0
def test_get_version_alembic(in_memory_sqlite, alembic_version_table):
    """Get the version of a sqlite with an alembic version table"""
    with in_memory_sqlite.get_engine().connect() as connection:
        connection.execute(
            alembic_version_table.insert().values(version_num="0201"))

    schema_checker = ModelSchema(in_memory_sqlite)
    migration_id = schema_checker.get_version()
    assert migration_id == 201
示例#3
0
def test_get_version_south(in_memory_sqlite, south_migration_table):
    """Get the version of a sqlite with a South version table"""
    with in_memory_sqlite.get_engine().connect() as connection:
        for v in (42, 43):
            connection.execute(south_migration_table.insert().values(id=v))

    schema_checker = ModelSchema(in_memory_sqlite)
    migration_id = schema_checker.get_version()
    assert migration_id == 43
示例#4
0
def test_upgrade_south_not_latest_errors(in_memory_sqlite):
    """Upgrading a database that is not at the latest south migration will error"""
    schema = ModelSchema(in_memory_sqlite)
    with mock.patch.object(schema,
                           "get_version",
                           return_value=constants.LATEST_SOUTH_MIGRATION_ID -
                           1):
        with pytest.raises(errors.MigrationMissingError):
            schema.upgrade(backup=False)
示例#5
0
def test_upgrade_without_backup(threedi_db):
    """Upgrading with backup=True will proceed on the database itself"""
    schema = ModelSchema(threedi_db)
    with mock.patch("threedi_modelchecker.schema._upgrade_database",
                    side_effect=RuntimeError) as upgrade, mock.patch.object(
                        schema, "get_version", return_value=199):
        with pytest.raises(RuntimeError):
            schema.upgrade(backup=False)

    (db, ), kwargs = upgrade.call_args
    assert db is threedi_db
示例#6
0
def test_upgrade_with_backup(threedi_db):
    """Upgrading with backup=True will proceed on a copy of the database"""
    if threedi_db.db_type != "spatialite":
        pytest.skip()
    schema = ModelSchema(threedi_db)
    with mock.patch("threedi_modelchecker.schema._upgrade_database",
                    side_effect=RuntimeError) as upgrade, mock.patch.object(
                        schema, "get_version", return_value=199):
        with pytest.raises(RuntimeError):
            schema.upgrade(backup=True)

    (db, ), kwargs = upgrade.call_args
    assert db is not threedi_db
示例#7
0
def migrate(ctx, revision):
    """Migrate the threedi model schematisation to the latest version."""
    schema = ModelSchema(ctx.obj["db"])
    click.echo("The current schema revision is: %s" % schema.get_version())
    click.echo("Running alembic upgrade script...")
    schema.upgrade(revision=revision)
    click.echo("The migrated schema revision is: %s" % schema.get_version())
示例#8
0
def test_validate_schema_missing_migration(threedi_db, version):
    """Validate a too low schema version"""
    schema = ModelSchema(threedi_db)
    with mock.patch.object(schema, "get_version", return_value=version):
        with pytest.raises(errors.MigrationMissingError):
            schema.validate_schema()
示例#9
0
def test_get_version_empty_alembic(in_memory_sqlite, alembic_version_table):
    """Get the version of a sqlite with an empty alembic version table"""
    schema_checker = ModelSchema(in_memory_sqlite)
    migration_id = schema_checker.get_version()
    assert migration_id is None
示例#10
0
def test_get_version_no_tables(in_memory_sqlite):
    """Get the version of a sqlite with no version tables"""
    schema_checker = ModelSchema(in_memory_sqlite)
    migration_id = schema_checker.get_version()
    assert migration_id is None
示例#11
0
def test_full_upgrade_oldest(oldest_sqlite):
    """Upgrade an empty database to the latest version"""
    schema = ModelSchema(oldest_sqlite)
    schema.upgrade(backup=False)
    assert schema.get_version() == get_schema_version()
    assert oldest_sqlite.get_engine().has_table("v2_connection_nodes")
示例#12
0
def test_validate_schema_too_high_migration(threedi_db, version):
    """Validate a too high schema version"""
    schema = ModelSchema(threedi_db)
    with mock.patch.object(schema, "get_version", return_value=version):
        with pytest.warns(UserWarning):
            schema.validate_schema()
 def check_schematisation(self):
     """Run schematisation checker."""
     try:
         from sqlalchemy.exc import OperationalError
         from threedi_modelchecker.threedi_database import ThreediDatabase
         from threedi_modelchecker.model_checks import ThreediModelChecker
         from threedi_modelchecker.schema import ModelSchema
         from threedi_modelchecker import errors
     except ImportError:
         raise
     db_settings = {"db_path": self.schematisation_sqlite}
     threedi_db = ThreediDatabase(db_settings)
     schema = ModelSchema(threedi_db)
     try:
         schema.validate_schema()
     except errors.MigrationMissingError:
         warn_and_ask_msg = (
             "The selected spatialite cannot be used because its database schema version is out of date. "
             "Would you like to migrate your spatialite to the current schema version?"
         )
         do_migration = self.communication.ask(None, "Missing migration",
                                               warn_and_ask_msg)
         if not do_migration:
             self.communication.bar_warn("Schematisation checks skipped!")
             return
         wip_revision = self.current_local_schematisation.wip_revision
         backup_filepath = wip_revision.backup_sqlite()
         schema.upgrade(backup=False, upgrade_spatialite_version=True)
         shutil.rmtree(os.path.dirname(backup_filepath))
     except errors.UpgradeFailedError:
         error_msg = (
             "There are errors in the spatialite. Please re-open this file in QGIS 3.16, run the model checker and "
             "fix error messages. Then attempt to upgrade again. For questions please contact the servicedesk."
         )
         self.communication.show_error(error_msg, self)
         return
     except Exception as e:
         error_msg = f"{e}"
         self.communication.show_error(error_msg, self)
         return
     model_checker = None
     try:
         model_checker = ThreediModelChecker(threedi_db)
         model_checker.db.check_connection()
     except OperationalError as exc:
         error_msg = (
             f"Failed to start a connection with the database.\n"
             f"Something went wrong trying to connect to the database, "
             f"please check the connection settings: {exc.args[0]}")
         self.communication.show_error(error_msg, self)
         return
     except errors.MigrationMissingError:
         error_msg = (
             "The selected 3Di model does not have the latest migration.\n"
             "The selected 3Di model does not have the latest migration,"
             "please migrate your model to the latest version.")
         self.communication.show_error(error_msg, self)
         return
     except errors.MigrationTooHighError:
         error_msg = (
             "The selected 3Di model has a higher migration than expected.\n"
             "The 3Di model has a higher migration than expected, "
             "do you have the latest version of ThreediToolbox?")
         self.communication.show_error(error_msg, self)
         return
     except errors.MigrationNameError:
         warn_msg = (
             "Unexpected migration name, but migration id is matching.\n"
             "We are gonna continue for now and hope for the best.")
         self.communication.bar_warn(warn_msg)
     session = model_checker.db.get_session()
     total_checks = len(model_checker.config.checks)
     self.pbar_check_spatialite.setMaximum(total_checks)
     self.pbar_check_spatialite.setValue(0)
     results_rows = []
     for i, check in enumerate(
             model_checker.checks(level=LogLevels.INFO.value), start=1):
         for result_row in check.get_invalid(session):
             results_rows.append([
                 check.level.name,
                 check.error_code,
                 result_row.id,
                 check.table.name,
                 check.column.name,
                 getattr(result_row, check.column.name),
                 check.description(),
             ])
         self.pbar_check_spatialite.setValue(i)
     if results_rows:
         for result_row in results_rows:
             level = result_row[0].upper()
             self.schematisation_checker_logger.log_result_row(
                 result_row, level)
     self.communication.bar_info("Finished schematisation checks.")
     self.pbar_check_spatialite.setValue(total_checks)
     self.pbar_check_spatialite.hide()
     self.lbl_check_spatialite.show()