Skip to content

Restore

Restore uploads emails from your local SQLite database back to an IMAP server. It preserves the original mailbox structure, flags (read/unread), and dates.

Why Restore?

  • Migration — move emails between servers (Hostinger to Gmail, Gmail to Outlook, etc.)
  • Disaster recovery — re-upload emails after a server failure
  • Account merge — consolidate multiple accounts into one
  • Testing — populate a test server with real data

Restore All Mailboxes

Each email is uploaded to its original mailbox. If a mailbox doesn't exist on the target server, it's created automatically.

# Code above omitted 👆

        # Force re-download (skip duplicate check)
        result = app.sync(skip_duplicates=False)


# Code below omitted 👇
👀 Full file preview
"""Sync and restore emails."""

from email_profile import Email


def main() -> None:
    with Email.from_env() as app:
        # Sync all mailboxes (compares by Message-ID)
        result = app.sync()
        print(f"Synced: {result.inserted} new, {result.skipped} skipped")

        # Sync one mailbox
        result = app.sync(mailbox="INBOX")
        print(f"INBOX: {result.inserted} new")

        # Force re-download (skip duplicate check)
        result = app.sync(skip_duplicates=False)

        # Restore all mailboxes to server (compares by Message-ID)
        count = app.restore()
        print(f"Restored {count} emails")

        # Restore one mailbox
        count = app.restore(mailbox="INBOX")
        print(f"Restored {count} to INBOX")

        # Force re-upload (skip duplicate check)
        count = app.restore(skip_duplicates=False)

        # Control parallelism
        result = app.sync(max_workers=5)
        count = app.restore(max_workers=5)


if __name__ == "__main__":
    main()

Restore One Mailbox

# Code above omitted 👆

        count = app.restore()
        print(f"Restored {count} emails")


# Code below omitted 👇
👀 Full file preview
"""Sync and restore emails."""

from email_profile import Email


def main() -> None:
    with Email.from_env() as app:
        # Sync all mailboxes (compares by Message-ID)
        result = app.sync()
        print(f"Synced: {result.inserted} new, {result.skipped} skipped")

        # Sync one mailbox
        result = app.sync(mailbox="INBOX")
        print(f"INBOX: {result.inserted} new")

        # Force re-download (skip duplicate check)
        result = app.sync(skip_duplicates=False)

        # Restore all mailboxes to server (compares by Message-ID)
        count = app.restore()
        print(f"Restored {count} emails")

        # Restore one mailbox
        count = app.restore(mailbox="INBOX")
        print(f"Restored {count} to INBOX")

        # Force re-upload (skip duplicate check)
        count = app.restore(skip_duplicates=False)

        # Control parallelism
        result = app.sync(max_workers=5)
        count = app.restore(max_workers=5)


if __name__ == "__main__":
    main()

Skip Duplicates

By default, restore checks if an email already exists on the server (by Message-ID) and skips it. Disable this for faster restores when you know the server is empty:

count = app.restore(skip_duplicates=False)

Parallel Workers

Like sync, restore uses threads — one per mailbox:

count = app.restore(max_workers=5)

Output

Each mailbox shows a progress bar while uploading:

  • uploaded — emails sent to the server
  • skipped — emails already on the server (duplicate detection)

Restore to a Different Server

Sync from one server, restore to another:

from email_profile import Email, StorageSQLite

storage = StorageSQLite("./backup.db")

# Step 1: sync from source server
with Email("user@old-server.com", "password") as source:
    source.sync()

# Step 2: restore to target server
with Email("user@new-server.com", "password", storage=storage) as target:
    count = target.restore()
    print(f"Migrated {count} emails")

What gets restored?

Data Restored?
Email content (RFC822) Yes
Mailbox/folder Yes (created if missing)
Flags (read/unread, flagged) Yes
Original date Yes (from Date header)
IMAP UID No (new UID assigned by server)

Reference