예제 #1
0
def get_physical_table_metadata(
    database: Database,
    table_name: str,
    schema_name: Optional[str] = None,
) -> List[Dict[str, Any]]:
    """Use SQLAlchemy inspector to get table metadata"""
    db_engine_spec = database.db_engine_spec
    db_dialect = database.get_dialect()
    # ensure empty schema
    _schema_name = schema_name if schema_name else None
    # Table does not exist or is not visible to a connection.

    if not (database.has_table_by_name(table_name=table_name,
                                       schema=_schema_name)
            or database.has_view_by_name(view_name=table_name,
                                         schema=_schema_name)):
        raise NoSuchTableError

    cols = database.get_columns(table_name, schema=_schema_name)
    for col in cols:
        try:
            if isinstance(col["type"], TypeEngine):
                db_type = db_engine_spec.column_datatype_to_string(
                    col["type"], db_dialect)
                type_spec = db_engine_spec.get_column_spec(
                    db_type, db_extra=database.get_extra())
                col.update({
                    "type":
                    db_type,
                    "type_generic":
                    type_spec.generic_type if type_spec else None,
                    "is_dttm":
                    type_spec.is_dttm if type_spec else None,
                })
        # Broad exception catch, because there are multiple possible exceptions
        # from different drivers that fall outside CompileError
        except Exception:  # pylint: disable=broad-except
            col.update({
                "type": "UNKNOWN",
                "type_generic": None,
                "is_dttm": None,
            })
    return cols
예제 #2
0
    def check_extra(self, database: Database) -> None:  # pylint: disable=no-self-use
        # this will check whether json.loads(extra) can succeed
        try:
            extra = database.get_extra()
        except Exception as ex:
            raise Exception(
                _("Extra field cannot be decoded by JSON. %{msg}s",
                  msg=str(ex)))

        # this will check whether 'metadata_params' is configured correctly
        metadata_signature = inspect.signature(MetaData)
        for key in extra.get("metadata_params", {}):
            if key not in metadata_signature.parameters:
                raise Exception(
                    _(
                        "The metadata_params in Extra field "
                        "is not configured correctly. The key "
                        "%{key}s is invalid.",
                        key=key,
                    ))