[GH-ISSUE #554] Database Migration #401

Closed
opened 2026-02-25 23:42:19 +03:00 by kerem · 1 comment
Owner

Originally created by @lettore on GitHub (Aug 22, 2021).
Original GitHub issue: https://github.com/healthchecks/healthchecks/issues/554

Hello, I'm running Healthchecks in Docker self hosted, I started with the builtin Sqlite database for testing, but now Healthchecks is vital for me.
I want to switch from Sqlite to Mysql for production use, but I don't want to configure again all the checks.
There's a way to export all the data and restore on a fresh installation using Mysql as database?
Thanks

Originally created by @lettore on GitHub (Aug 22, 2021). Original GitHub issue: https://github.com/healthchecks/healthchecks/issues/554 Hello, I'm running Healthchecks in Docker self hosted, I started with the builtin Sqlite database for testing, but now Healthchecks is vital for me. I want to switch from Sqlite to Mysql for production use, but I don't want to configure again all the checks. There's a way to export all the data and restore on a fresh installation using Mysql as database? Thanks
kerem 2026-02-25 23:42:19 +03:00
  • closed this issue
  • added the
    question
    label
Author
Owner

@cuu508 commented on GitHub (Aug 23, 2021):

I don't have experience with this, and don't have solid advice to give. But here's two things to investigate.

  1. Healthchecks is a fairly conventional Django app. You can expand the search to "how to migrate a Django app from one database type to another", and see what suggestions come up.

  2. I once had to selectively restore one customer's account from a backup that was deleted by user mistake. To do this, I wrote two management commands. One command, export.py, exports a single account's data in a JSON file. The other command, restore.py, reads the JSON file and inserts it in the database. The same approach may work for DB migration as well – export from SQLite, then import in MySQL.

Here are the management commands I used – if you use them please be sure to check the migrated data is not missing anything. If you notice any weirdness, please let me know about it.

export.py:

from itertools import chain

from django.core.management.base import BaseCommand
from django.core.serializers import serialize

from django.contrib.auth.models import User
from hc.accounts.models import Credential, Profile, Project
from hc.api.models import Channel, Check, Flip, Notification, Ping


class Command(BaseCommand):
    help = """Export a single account's data in a JSON format."""

    def handle(self, *args, **options):
        email = "foo@example.org"

        user_q = User.objects.filter(email=email)
        credential_q = Credential.objects.filter(user__email=email)
        profile_q = Profile.objects.filter(user__email=email)
        project_q = Project.objects.filter(owner__email=email)
        check_q = Check.objects.filter(project__owner__email=email)
        channel_q = Channel.objects.filter(project__owner__email=email)
        ping_q = Ping.objects.filter(owner__project__owner__email=email)
        flip_q = Flip.objects.filter(owner__project__owner__email=email)
        notification_q = Notification.objects.filter(owner__project__owner__email=email)

        chained = chain(
            user_q,
            credential_q,
            profile_q,
            project_q,
            check_q,
            channel_q,
            ping_q,
            notification_q,
            flip_q,
        )

        print(serialize("json", chained, indent=2))

restore.py:

from django.core.management.base import BaseCommand
from django.core.serializers import deserialize


class Command(BaseCommand):
    help = """Export a single account's data in a JSON format."""

    def handle(self, *args, **options):
        f = open("foo_at_example_org.json", "r")
        for i, obj in enumerate(deserialize("json", f)):
            obj.save(force_insert=True)

            if i % 1000 == 0:
                print(i)
<!-- gh-comment-id:903503456 --> @cuu508 commented on GitHub (Aug 23, 2021): I don't have experience with this, and don't have solid advice to give. But here's two things to investigate. 1. Healthchecks is a fairly conventional Django app. You can expand the search to "how to migrate a *Django* app from one database type to another", and see what suggestions come up. 2. I once had to selectively restore one customer's account from a backup that was deleted by user mistake. To do this, I wrote two management commands. One command, `export.py`, exports **a single account's data** in a JSON file. The other command, `restore.py`, reads the JSON file and inserts it in the database. The same approach may work for DB migration as well – export from SQLite, then import in MySQL. Here are the management commands I used – if you use them please be sure to check the migrated data is not missing anything. If you notice any weirdness, please let me know about it. export.py: ```python from itertools import chain from django.core.management.base import BaseCommand from django.core.serializers import serialize from django.contrib.auth.models import User from hc.accounts.models import Credential, Profile, Project from hc.api.models import Channel, Check, Flip, Notification, Ping class Command(BaseCommand): help = """Export a single account's data in a JSON format.""" def handle(self, *args, **options): email = "foo@example.org" user_q = User.objects.filter(email=email) credential_q = Credential.objects.filter(user__email=email) profile_q = Profile.objects.filter(user__email=email) project_q = Project.objects.filter(owner__email=email) check_q = Check.objects.filter(project__owner__email=email) channel_q = Channel.objects.filter(project__owner__email=email) ping_q = Ping.objects.filter(owner__project__owner__email=email) flip_q = Flip.objects.filter(owner__project__owner__email=email) notification_q = Notification.objects.filter(owner__project__owner__email=email) chained = chain( user_q, credential_q, profile_q, project_q, check_q, channel_q, ping_q, notification_q, flip_q, ) print(serialize("json", chained, indent=2)) ``` restore.py: ```python from django.core.management.base import BaseCommand from django.core.serializers import deserialize class Command(BaseCommand): help = """Export a single account's data in a JSON format.""" def handle(self, *args, **options): f = open("foo_at_example_org.json", "r") for i, obj in enumerate(deserialize("json", f)): obj.save(force_insert=True) if i % 1000 == 0: print(i) ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/healthchecks#401
No description provided.