apache/superset · error · ValueError

Database not found

Error message

Database not found

What it means

Plain ValueError('Database not found') raised at the top of DatabaseDAO.is_odps_partitioned_table: the caller passed a falsy `database` (None or an unloaded/empty object). Everything after it (ODPS backend check, pyodps import guard, URI parsing) assumes a real Database instance.

Source

Thrown at superset/daos/database.py:275

                SqlaTable.database_id == database_id,
                SqlaTable.catalog == catalog,
                SqlaTable.schema == schema,
            )
            .all()
        )

    @classmethod
    def is_odps_partitioned_table(
        cls, database: Database, table_name: str
    ) -> tuple[bool, list[str]]:
        """
        This function is used to determine and retrieve
        partition information of the ODPS table.
        The return values are whether the partition
        table is partitioned and the names of all partition fields.
        """
        if not database:
            raise ValueError("Database not found")
        if database.backend != "odps":
            return False, []
        if ODPS is None:
            logger.warning("pyodps is not installed, cannot check ODPS partition info")
            return False, []
        uri = database.sqlalchemy_uri
        access_key = database.password
        pattern = re.compile(
            r"odps://(?P<username>[^:]+):(?P<password>[^@]+)@(?P<project>[^/]+)/(?:\?"
            r"endpoint=(?P<endpoint>[^&]+))"
        )
        if not uri or not isinstance(uri, str):
            logger.warning(
                "Invalid or missing sqlalchemy URI, please provide a correct URI"
            )
            return False, []
        if match := pattern.match(unquote(uri)):
            access_id = match.group("username")

View on GitHub (pinned to f4587218dd)

Solutions

  1. Resolve and verify the Database before calling: `db_obj = DatabaseDAO.find_by_id(id); if db_obj is None: raise/handle` then call with db_obj.
  2. Guard at the call site with a truthiness check when the database is optional in your flow.

Example fix

# before
database = DatabaseDAO.find_by_id(maybe_missing_id)
parts = DatabaseDAO.is_odps_partitioned_table(database, "my_table")

# after
database = DatabaseDAO.find_by_id(maybe_missing_id)
if database is None:
    raise DatabaseNotFoundError()  # or return early
parts = DatabaseDAO.is_odps_partitioned_table(database, "my_table")
Defensive patterns

Strategy: type-guard

Validate before calling

def has_database(database) -> bool:
    return database is not None

Type guard

from superset.models.core import Database

def is_loaded_database(obj) -> bool:
    return isinstance(obj, Database) and obj.id is not None

Try / catch

try:
    DatabaseDAO.is_odps_partitioned_table(database, table)
except ValueError as ex:
    if ex.args[0] == "Database not found":
        # upstream lookup missed: re-raise as a 404-style error
        raise DatabaseNotFoundError() from ex
    raise

Prevention

When it happens

Trigger: Calling DatabaseDAO.is_odps_partitioned_table(None, table_name), or passing a database variable that came back None from a prior lookup (e.g. find_by_id miss) without checking.

Common situations: Fork/plugin code doing `db = DatabaseDAO.find_by_id(i); DatabaseDAO.is_odps_partitioned_table(db, t)` where the id doesn't exist; dataset flows where dataset.database resolved to None.

Related errors


AI-assisted analysis of apache/superset@f4587218dd (2026-08-14). Data as JSON: /api/errors/7da4c367b1c6d040. Report an issue: GitHub.