Skip to content

No migration metrics if using non-default DB alias #500

@OscarVanL

Description

@OscarVanL

Background

I have a Django application where I use explicitly named database aliases and not default:

    DATABASES = {
        'default': {
            'ENGINE': '',
        },
        'db1': {
            'ENGINE': 'django_prometheus.db.backends.mysql',
        },
        'db2': {
            'ENGINE': 'django_prometheus.db.backends.mysql',
        },
        ...
    }

The reason I use this design choice is because people repeatedly forgot to apply migrations because they ran python manage.py migrate assuming they had ran migrations all databases, when infact they had not ran migrations on the intended DB (as they forgot to run with the --database $ALIAS arg).

Now if a developer unintentionally does python manage.py migrate the command fails with an error which is intentional as we rather they be explicit.

I was surprised to see that no django_migrations_unapplied_total or django_migrations_applied_total metrics were being exported by my application.

Cause

I had a look at the code and it does this:

    if "default" in connections and (isinstance(connections["default"], DatabaseWrapper)):
        # This is the case where DATABASES = {} in the configuration,
        # i.e. the user is not using any databases. Django "helpfully"
        # adds a dummy database and then throws when you try to
        # actually use it. So we don't do anything, because trying to
        # export stats would crash the app on startup.
        return
    for alias in connections.databases:
        executor = MigrationExecutor(connections[alias])
        ExportMigrationsForDatabase(alias, executor)

Because of the first if-statement, my application will always skip without exporting any metrics.

Fix

I think it needs to be rewritten to conditionally skip the default database only:

    for alias in connections.databases:
        # This is the case where DATABASES = {} in the configuration,
        # i.e. the user is not using any databases. Django "helpfully"
        # adds a dummy database and then throws when you try to
        # actually use it. So we don't do anything, because trying to
        # export stats would crash the app on startup.
        if alias == "default" and (isinstance(connections[alias], DatabaseWrapper)):
            continue
        
        executor = MigrationExecutor(connections[alias])
        ExportMigrationsForDatabase(alias, executor)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions