Skip to main content

A package to upload Pandas DataFrame to Redshift

Project description

df_to_rs

df_to_rs is a Python package that provides efficient methods to upload, upsert and manage Pandas DataFrames in Amazon Redshift using S3 as an intermediary.

Key Features

  • Direct DataFrame to Redshift upload
  • Upsert functionality (update + insert)
  • Delete and insert operations
  • Large dataset handling with chunking
  • Support for JSON/dict/list columns (Redshift SUPER)
  • AWS IAM Role support for secure authentication
  • Automatic cleanup of temporary S3 files
  • Optimized NULL handling in upsert operations
  • Proper NULL value preservation across all data types

Installation

pip install df_to_rs

Usage

1. Initialize with AWS Credentials

from df_to_rs import df_to_rs
import psycopg2

# Connect to Redshift
redshift_conn = psycopg2.connect(
    dbname='your_db',
    host='your-cluster.region.redshift.amazonaws.com',
    port=1433,
    user='your_user',
    password='your_password'
)
redshift_conn.set_session(autocommit=True)

# Initialize with explicit credentials
uploader = df_to_rs(
    region_name='ap-south-1',
    s3_bucket='your-s3-bucket',
    aws_access_key_id='your-access-key-id',
    aws_secret_access_key='your-secret-access-key',
    redshift_c=redshift_conn
)

2. Initialize using EC2 Instance Role (Recommended)

# No AWS credentials needed when using instance role
uploader = df_to_rs(
    region_name='ap-south-1',
    s3_bucket='your-s3-bucket',
    redshift_c=redshift_conn
)

3. Basic Upload

Upload a DataFrame to a Redshift table:

# Simple upload
uploader.upload_to_redshift(
    df=your_dataframe,
    dest='schema.table_name'
)

4. Upsert Operation

Update existing records and insert new ones based on key columns:

# Upsert based on specific columns
uploader.upsert_to_redshift(
    df=your_dataframe,
    dest_table='schema.table_name',
    upsert_columns=['id', 'unique_key'],  # Columns to match existing records
    clear_dest_table=False  # Set True to truncate table before insert
)

Optimized NULL Handling in Upserts

The package includes optimized handling for NULL values in upsert key columns:

  • Automatically splits processing for records with and without NULL values in key columns
  • Uses simplified SQL for non-NULL records (better performance)
  • Correctly matches records where keys contain NULL values
  • Handles compound keys with a mix of NULL and non-NULL values
  • Preserves NULL values in all data types (including numeric columns) during transfer
# Example with NULL values in key columns
df = pd.DataFrame({
    'id': [1, 2, 3, None],
    'code': ['A', 'B', None, 'D'],
    'value': [100, 200, 300, 400]
})

# Correctly handles NULL matching in any key column
# and preserves NULLs in all column types
uploader.upsert_to_redshift(
    df=df,
    dest_table='schema.table_name',
    upsert_columns=['id', 'code']
)

5. Delete and Insert

Delete records matching a condition and insert new data:

# Delete and insert with condition
uploader.delete_and_insert_to_redshift(
    df=your_dataframe,
    dest_table='schema.table_name',
    filter_cond="date >= CURRENT_DATE - 7"  # SQL condition for deletion
)

# Delete and insert with timestamp precision
uploader.delete_and_insert_to_redshift(
    df=your_dataframe,
    dest_table='schema.table_name',
    filter_cond="date >= CURRENT_DATE - 7",  # SQL condition for broad deletion
    min_timestamp='2024-06-01 00:00:00',     # Minimum timestamp value from DataFrame
    timestamp_col='created_at'               # Column to use for timestamp filtering
)

Special Data Types

NULL Value Handling

The package properly preserves NULL values in all data types:

# DataFrame with NULL values in different data types
df = pd.DataFrame({
    'id': [1, 2, None, 4],                       # Integer with NULL
    'value': [10.5, None, 30.75, 40.25],         # Float with NULL
    'code': ['A', 'B', None, 'D'],               # String with NULL
    'date': [date(2025,1,1), None, date(2025,3,1), date(2025,4,1)]  # Date with NULL
})

# All NULL values will be properly preserved in Redshift
uploader.upload_to_redshift(df, 'schema.table_name')

JSON/Dictionary Columns

The package automatically handles JSON/dict/list columns for Redshift SUPER type:

# DataFrame with JSON column
df = pd.DataFrame({
    'id': [1, 2],
    'json_data': [{'key': 'value'}, {'other': 'data'}]
})

# Will be automatically converted for Redshift SUPER column
uploader.upload_to_redshift(df, 'schema.table_name')

Large Dataset Handling

The package automatically handles large datasets by:

  • Chunking data into 1 million row segments
  • Streaming to S3 in memory
  • Automatic cleanup of temporary files
  • Progress tracking with timestamps

Error Handling

  • Automatic transaction rollback on errors
  • S3 temporary file cleanup
  • Detailed error messages and timestamps
  • Safe staging table management for upserts

AWS IAM Role Requirements

When using instance roles, ensure your role has these permissions:

  • S3: PutObject, GetObject, DeleteObject on the specified bucket
  • Redshift: COPY command permissions
  • IAM: AssumeRole permissions if needed

Best Practices

  1. Use instance roles instead of access keys when possible
  2. Set appropriate column types in Redshift, especially for SUPER columns
  3. Create tables with appropriate sort and dist keys before uploading
  4. Monitor the Redshift query logs for performance optimization

License

This project is licensed under the MIT License - see the LICENSE file for details

Changelog

All notable changes to df_to_rs will be documented in this file.

[0.1.27] - 2025-05-05

Fixed

  • Improved NULL value handling in DataFrames to ensure proper conversion to Redshift NULL values
  • Fixed issue where NULL values were being converted to empty strings in Redshift
  • Added proper NULL handling for numeric columns during data transfer
  • Standardized NULL representation using 'NULL' in CSV files and COPY commands

[0.1.26] - 2025-05-04

Added

  • Optimized NULL handling in upsert operations
  • Split processing for records with and without NULL values in key columns
  • Improved SQL generation for better performance with NULL key values
  • Added explicit handling of NULL columns in upsert operations

Changed

  • Enhanced documentation for NULL handling features
  • Improved logging and timing information for NULL vs non-NULL operations

[0.1.25] - 2025-04-15

Added

  • Enhanced delete_and_insert_to_redshift with additional timestamp-based deletion to ensure no duplicates
  • Added support for min_timestamp and timestamp_col parameters for more precise data control

[0.1.24] - 2025-01-26

Added

  • Documentation Improved

[0.1.23] - 2025-01-26

Added

  • Support for instance role-based authentication in AWS
  • Handling of JSON/dict/list objects for Redshift SUPER columns
  • Proper cleanup of S3 temporary files

Changed

  • Made AWS credentials optional in constructor
  • Optimized DataFrame processing with unified applymap operations
  • Improved string column handling for better type safety

Fixed

  • S3 resource cleanup in error scenarios
  • Transaction handling in delete_and_insert_to_redshift

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

df_to_rs-0.1.27.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

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

df_to_rs-0.1.27-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file df_to_rs-0.1.27.tar.gz.

File metadata

  • Download URL: df_to_rs-0.1.27.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.9

File hashes

Hashes for df_to_rs-0.1.27.tar.gz
Algorithm Hash digest
SHA256 12f8df6b67710c1e9f20efefbcebd7a52a84820efc8290b099ca41fed35422ce
MD5 6fc9eeec7d94277af1ae8f462ac52e6c
BLAKE2b-256 5585b19bca88ce58df937c5752058814ebed6491a458d863ad21eca2c7af0f2b

See more details on using hashes here.

File details

Details for the file df_to_rs-0.1.27-py3-none-any.whl.

File metadata

  • Download URL: df_to_rs-0.1.27-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.10.9

File hashes

Hashes for df_to_rs-0.1.27-py3-none-any.whl
Algorithm Hash digest
SHA256 8c3975d49735482029e138958c3524805e8c0c36969d75f30996e83fd0d9a512
MD5 3f09e68ca0c6070d79ec8bffe5d89796
BLAKE2b-256 168f7a9750ed5675d900e4c3b06b984559b3723840174fcf6465928ded54719c

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