Skip to main content

Archive PostgreSQL tables to Parquet files on S3 with safety, restore, and retention management.

Project description

Backparq

Archive PostgreSQL tables to Parquet files on S3 with safety, restore, and retention management.

Python 3.9+ PyPI License: MIT

Features

  • Archive & Offload - Move cold data to S3 Parquet, optionally delete from DB
  • Backup Mode - Full table snapshots for disaster recovery
  • Safety First - SHA256 checksums verified before any data deletion
  • Schema Evolution - Restore handles dropped columns automatically
  • Parallel Processing - Table-level and chunk-level concurrency
  • Graceful Shutdown - Clean interruption on SIGINT/SIGTERM

Installation

pip install backparq

With optional features:

pip install backparq[all]      # All optional dependencies
pip install backparq[query]    # DuckDB for querying archives
pip install backparq[metrics]  # Prometheus metrics

Quick Start

# Generate config interactively
backparq init

# Test connections
backparq test --config backparq.yaml

# Run archive (dry-run first)
backparq archive --config backparq.yaml --dry-run -v

# Run archive
backparq archive --config backparq.yaml -v --stats

Commands

usage: backparq [-h] [-v] {test,archive,apply,restore,check,prune,status,verify,init} ...

Commands:
  test      Test connections
  archive   Archive tables to Parquet/S3
  apply     Archive and install cron
  restore   Restore from archive
  check     List S3 backups
  prune     Delete old backups
  status    Show archive status
  verify    Verify archive integrity
  init      Generate config file

Options:
  -v, --verbose   Verbosity (-v INFO, -vv DEBUG)

archive

backparq archive --config config.yaml --stats
backparq archive --config config.yaml --output json

restore

backparq restore --config config.yaml --start 2024-01-01 --end 2024-04-01
backparq restore --config config.yaml --start 2024-01-01 --end 2024-04-01 --conflict-mode upsert

status

backparq status --config config.yaml
backparq status --config config.yaml --table events --output json

verify

backparq verify --config config.yaml
backparq verify --config config.yaml --repair

Configuration

Basic

database:
  host: localhost
  port: 5432
  name: mydb
  user: postgres
  password: "${PG_PASSWORD}"

s3:
  bucket: my-backup-bucket
  prefix: db-archive
  region: us-east-1

archive:
  mode: offload
  tables:
    - public.events
    - public.orders

Table Primary Keys

archive:
  tables:
    - public.events                    # Uses default "id"
    - table: public.orders
      primary_key: order_id            # Custom primary key

The primary_key is used during restore --conflict-mode upsert to detect and update existing rows.

Full Example

database:
  host: localhost
  port: 5432
  name: production
  user: backup_user
  password: "${PG_PASSWORD}"
  sslmode: require

s3:
  bucket: company-backups
  prefix: postgres/archive
  region: us-east-1
  access_key_id: "${AWS_ACCESS_KEY_ID}"
  secret_access_key: "${AWS_SECRET_ACCESS_KEY}"
  sse: aws:kms
  kms_key_id: alias/backup-key

archive:
  mode: offload
  order_by: created_at
  cutoff: -90d
  perform_delete: false
  concurrency: 2
  base_dir: ./backparq-data

  tables:
    - public.events
    - table: public.orders
      primary_key: order_id

  retention:
    enabled: true
    days: 365

parquet:
  compression: zstd
  row_group_size: 100000

Archive Modes

Offload Mode (Default)

Archives data older than cutoff date, partitioned by month.

archive:
  mode: offload
  order_by: created_at
  cutoff: -90d
  perform_delete: true

Backup Mode

Creates full table snapshots with unique run ID.

archive:
  mode: backup

Restore from snapshot:

backparq restore --config config.yaml --backup-id 2024-01-15_120000 --start 2024-01-01 --end 2024-02-01

Testing

Local with MinIO

# Start MinIO
docker run -d -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin \
  minio/minio server /data --console-address ":9001"

# Create config
cat > config.yaml << 'EOF'
database:
  host: localhost
  port: 5432
  name: testdb
  user: postgres
  password: postgres

s3:
  bucket: test-bucket
  prefix: backparq
  endpoint_url: http://localhost:9000
  access_key_id: minioadmin
  secret_access_key: minioadmin
  addressing_style: path

archive:
  mode: offload
  tables:
    - public.test_table
EOF

# Test
backparq test --config config.yaml
backparq archive --config config.yaml -v --stats

Development

# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Type check
mypy src/backparq

# Lint
ruff check src/

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

backparq-0.1.0.tar.gz (37.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

backparq-0.1.0-py3-none-any.whl (35.9 kB view details)

Uploaded Python 3

File details

Details for the file backparq-0.1.0.tar.gz.

File metadata

  • Download URL: backparq-0.1.0.tar.gz
  • Upload date:
  • Size: 37.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for backparq-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b375776fa55018b78c43585b8c1115ff20ab1ffebbbeccb4c446e208d8211afa
MD5 0589a6554b6bdadbcfeb1e3e2c7c09a5
BLAKE2b-256 9ab4b3dabb1f387668e97d30ac5dd4589bcc883b71c6a940b8f7d7d17843657f

See more details on using hashes here.

File details

Details for the file backparq-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: backparq-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 35.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for backparq-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4e8be410232f91d925293e4965f809821f2e349f427a36886674151ae9dae33a
MD5 42bd51ec1e38f6b623624b12f7ef2ba0
BLAKE2b-256 a7bd89e8622bfe79b6bb53ea5975a62811a0bd1ca2ee7df72a20c9d867f9c01c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page