Skip to main content
The backups service provides automated and manual database backup functionality with intelligent cleanup and restoration capabilities.

Overview

Location: services/backups.py This module handles:
  • On-demand database backups
  • Automated daily backup scheduling
  • Backup file management and cleanup
  • Database restoration from backup files
  • Backup listing and metadata

Configuration

DB_PATH
Path
Database file path from data.db.session.DB_PATH
MAX_BACKUPS
int
default:20
Maximum number of backup files to retain
TZ
ZoneInfo
default:"America/Hermosillo"
Timezone for backup timestamps
Backup files are stored in a backups/ directory alongside the database file. The directory is automatically created if it doesn’t exist.

Functions

create_backup_now

Creates an immediate backup of the database using SQLite’s backup API. Parameters: None Returns: Optional[Path] - Path to the created backup file, or None if backup failed
from services.backups import create_backup_now

# Create a manual backup
backup_path = create_backup_now()

if backup_path:
    print(f"Backup created: {backup_path}")
    print(f"File size: {backup_path.stat().st_size} bytes")
else:
    print("Backup failed")
This function uses SQLite’s built-in backup API, which is more reliable than file copying as it handles concurrent access and ensures data consistency.

create_backup_if_needed

Creates a backup only if one hasn’t been created today. Parameters: None Returns: Optional[Path] - Path to the created backup file, or None if backup wasn’t needed or failed
from services.backups import create_backup_if_needed

# Called during application startup
backup_path = create_backup_if_needed()

if backup_path:
    print(f"Daily backup created: {backup_path}")
else:
    print("Daily backup not needed or failed")
This function checks the last_backup_at timestamp in settings.json. If a backup already exists for the current day (Hermosillo timezone), it skips creating a new one.

list_backups

Returns a list of all available backup files with metadata. Parameters: None Returns: List[Dict] - List of backup information dictionaries Each dictionary contains:
  • path (Path): Full path to the backup file
  • name (str): Filename
  • display (str): Formatted timestamp (dd/mm/yyyy hh:mm)
  • size (int): File size in bytes
from services.backups import list_backups

backups = list_backups()

print(f"Found {len(backups)} backups:")
for backup in backups:
    size_mb = backup['size'] / (1024 * 1024)
    print(f"  {backup['display']}: {backup['name']} ({size_mb:.2f} MB)")
Backups are sorted by modification time in descending order, so the most recent backup appears first.

restore_backup

Restores the database from a backup file.
backup_path
Path
required
Path to the backup file to restore from
Returns: bool - True if restoration succeeded, False otherwise
from services.backups import list_backups, restore_backup
from pathlib import Path

backup_file = Path("/path/to/backups/backup_20260304_150000.db")

if restore_backup(backup_file):
    print("Database restored successfully")
    print("Restart the application to use the restored database")
else:
    print("Failed to restore database")
This function creates a safety backup of the current database before overwriting it. The safety backup is saved with a .before_restore_TIMESTAMP suffix. Always ensure you have recent backups before performing a restore.

get_last_backup_display

Returns a formatted string showing when the last backup was created. Parameters: None Returns: str - Formatted timestamp or ”—” if no backup exists
from services.backups import get_last_backup_display

# Display in status bar or UI
last_backup = get_last_backup_display()
print(f"Last backup: {last_backup}")
# Output: Last backup: 04/03/2026 15:30
# or: Last backup: —

Backup Management

Automatic Cleanup

The service automatically maintains the backup directory:
  • Keeps only the most recent MAX_BACKUPS files (default: 20)
  • Older backups are automatically deleted
  • Cleanup runs after each new backup creation

Backup File Naming

Backup files follow this naming pattern:
backup_YYYYMMDD_HHMMSS.db
Examples:
  • backup_20260304_153045.db - March 4, 2026 at 15:30:45
  • backup_20260303_030000.db - March 3, 2026 at 03:00:00

Storage Location

Backups are stored in:
<database_directory>/backups/
For example, if your database is at /data/studio.db, backups will be in /data/backups/.

Backup Strategy

1

Automatic daily backups

Call create_backup_if_needed() during application startup or via scheduled task.
2

Manual backups before critical operations

Use create_backup_now() before major data migrations or system changes.
3

Verify backups regularly

Use list_backups() to confirm backups are being created and stored properly.
4

Test restoration

Periodically test the restore process in a non-production environment.

Best Practices

The default daily backup schedule is suitable for most tattoo studios. For high-volume studios, consider creating manual backups during peak hours or before closing.
The backup service stores files locally. Implement additional off-site backup mechanisms by copying the backup files to cloud storage or external drives.
The default 20 backup retention allows for approximately 3 weeks of daily backups. Adjust MAX_BACKUPS based on your storage capacity and compliance requirements.
Monitor the size of backup files using list_backups(). Significant size increases may indicate data accumulation that needs attention.

Error Handling

All functions handle errors gracefully:
  • create_backup_now() returns None on failure and cleans up incomplete files
  • restore_backup() creates a safety backup before attempting restoration
  • Failed backups don’t update the last_backup_at timestamp
  • Database connections are properly closed even on exceptions

Backup & Restore Guide

User guide for backup and restoration procedures

Database Session

Database connection and session management

Build docs developers (and LLMs) love