Migrate Grafana from SQLite to an External Database (PostgreSQL / MySQL)¶
This guide walks you through migrating Grafana from its default embedded SQLite database to an external PostgreSQL or MySQL database. Custom folders, dashboards, alert rule groups, and contact points that exist only in the old SQLite database will be lost if you do not export them before switching and import them afterward. Follow every step in order.
Note
Privacera-managed dashboards, alerts, and folders are excluded from export and are automatically restored by the Post Install Job.
Migration Workflow¶
- (Optional) Back up Internal SQLite Grafana database.
- Enter the Privacera Manager container (Python is pre-installed).
- Export custom assets with
grafana_export.py— run the export script before the DB switch. - Exit the container (the bundle is saved under
output/grafana-migration/on the jumphost). - Switch Grafana to an external database.
- Re-enter the container and import custom assets with
grafana_import.py.
Files You Need¶
| File | Purpose | When to run |
|---|---|---|
grafana_export.py | Exports custom assets to a local bundle | Before the DB switch |
grafana_import.py | Restores custom assets from the bundle | After the DB switch |
(Optional) Back Up Internal SQLite Grafana Database¶
For a safer recovery path, copy the SQLite database file from the Grafana pod before exporting or switching databases.
Step 1: Enter the PM Container¶
Step 2: Copy grafana.db to the Backup Path¶
Run inside the container:
| Bash | |
|---|---|
Step 3: Verify the Backup¶
| Bash | |
|---|---|
The backup is saved at /privacera/privacera-manager/output/grafana.db.backup on the jumphost.
Export Custom Assets (Before DB Switch)¶
The export script reads custom Grafana folders, dashboards, alert rule groups, and contact points over the HTTP API and writes them to a bundle directory. Privacera-managed assets are excluded automatically.
Step 1: Enter the PM Container¶
Skip this step if you are already inside the container from the optional backup step.
Step 2: Download the Export Script¶
Download the export script inside the container:
| Bash | |
|---|---|
Step 3: Verify the Download¶
| Bash | |
|---|---|
Step 4: Run the Export Script¶
Run the export script (still inside the container). There are two ways to authenticate with Grafana. Option 1 (username and password) is the default for most environments.
Bundle path
Use --output output/grafana-migration. From inside the container, run export and import from /privacera/privacera-manager so the bundle is written under output/grafana-migration/.
| Bash | |
|---|---|
Example:
Create an Admin service account token:
- Log in to Grafana as an administrator.
- Go to Administration > Users and access > Service accounts.
- Select Add service account, assign the Admin role, and save.
- Open the service account and select Add service account token.
- Copy the token immediately (starts with
glsa_...). It is shown only once.
| Bash | |
|---|---|
Example:
Optional flags:
--verbose— print each exported item--dry-run— preview without writing files
Review the Export Bundle¶
After export completes, custom data is stored as JSON under output/grafana-migration/.
Example summary:
| Text Only | |
|---|---|
Bundle Layout¶
| Text Only | |
|---|---|
Step 1: Confirm Counts in manifest.json¶
| Bash | |
|---|---|
Step 2: Exit the Container¶
| Bash | |
|---|---|
The bundle is now available at /privacera/privacera-manager/output/grafana-migration/ on the jumphost.
Switch Grafana to the External Database¶
Follow all steps in the Grafana High Availability (HA) guide to configure Grafana with the external database and apply the configuration.
Once Grafana has restarted, verify it is healthy and connected to the new database before proceeding:
| Bash | |
|---|---|
Expected response includes "database":"ok". Do not proceed to the import step until you see this.
Import Custom Assets¶
The import script restores custom assets from the bundle. Import order: folders → contact points → dashboards → alert rules.
Step 1: Re-enter the PM Container¶
Step 2: Download the Import Script¶
Download the import script inside the container:
| Bash | |
|---|---|
Step 3: Verify the Download¶
| Bash | |
|---|---|
Step 4: Run the Import Script¶
Run the import script (still inside the container). There are two ways to authenticate with Grafana. Option 1 (username and password) is the default for most environments.
| Bash | |
|---|---|
Example:
Create a new Admin service account token after the DB switch (old tokens are invalidated):
- Log in to Grafana as an administrator.
- Go to Administration > Users and access > Service accounts.
- Select Add service account, assign the Admin role, and save.
- Open the service account and select Add service account token.
- Copy the token immediately (starts with
glsa_...). It is shown only once.
| Bash | |
|---|---|
Example:
Optional flags:
--verbose— print each imported item
Review the Import¶
After the import script completes, review the output in the terminal. A successful run reports errors: 0 in the summary.
Example output:
| Text Only | |
|---|---|
To list each imported item as it is processed, add --verbose to the import command:
| Bash | |
|---|---|
Step 1: Confirm the Imported Assets¶
In your external PostgreSQL or MySQL database, confirm that Grafana tables contain the imported records.
Step 2: Exit the Container¶
| Bash | |
|---|---|
Troubleshooting¶
| Issue | Solution |
|---|---|
ModuleNotFoundError: No module named 'requests' | Python requests library is pre-installed in the PM container. If you see this error, you are running the script outside the container. Enter the container with ./privacera-manager.sh shell and try again. |
401 Unauthorized | API token or password is invalid or expired. Create a new Admin service account token (see authentication steps above). |
403 Forbidden | Service account lacks Admin role. Create a new token with Admin role. |
| SyntaxError when running script | Ensure you are using Python 3. The PM container has python3 pre-installed. |
| Dashboard/Alert already exists | The import script uses overwrite: true for dashboards and upsert semantics for alerts and contact points. Existing assets are updated, not duplicated. |
| Bundle not found after exiting container | The bundle must be written under output/grafana-migration/ inside /privacera/privacera-manager. If you used a different path, it may not persist on the jumphost. Re-run export with --output output/grafana-migration. |
Summary¶
This guide walked you through:
- (Optional) Backing up Internal SQLite Grafana database before switching databases.
- Exporting custom Grafana assets (folders, dashboards, alerts, contact points) before switching to an external database.
- Switching Grafana from the internal SQLite database to an external database.
- Importing the custom assets after the database switch.
Privacera-managed assets are automatically excluded from export and restored by the Post Install Job. The migration scripts run entirely inside the Privacera Manager container, where Python and all dependencies are pre-installed.