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.2.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.2.0-py3-none-any.whl (35.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: backparq-0.2.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.2.0.tar.gz
Algorithm Hash digest
SHA256 a20c14831e614c57744ea84b191f75a2f4d84e574eca0dd7a79c0648849eadc0
MD5 f0239f20bb3c0fd47d01fc00fde96574
BLAKE2b-256 9ffb7ca8bc4790e564bc667ec9c77c88a6f610091d9bf3bbfbe2e58240539794

See more details on using hashes here.

File details

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

File metadata

  • Download URL: backparq-0.2.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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c57d6469000c73302fdf939e6a1e664a1b34be7956bc23c0cd44ee6ddc1a1739
MD5 08bf7398e27beeb93a7c940cde8db845
BLAKE2b-256 40476a9455dbadcc57a83d325279b3f945ea83228f2b30a31b87be71199b9082

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