迁移至Python3.6:如何用Boto3与DynamoDB Scan查询日期区间数据?
Replicating Node.js DynamoDB Date Range Query with Boto3 (Python 3.6)
Got it, let's translate your Node.js DynamoDB date range query over to Python 3.6 using Boto3. I'll mirror your original logic step by step so it feels familiar:
Step 1: Set Up Dependencies
First, you'll need a couple of packages since Python 3.6 doesn't include full timezone support in the standard library. Install them via pip:
pip install boto3 pytz python-dotenv
boto3: The official AWS SDK for Pythonpytz: Handles timezone conversions (since Python 3.6 lacks the newerzoneinfomodule)python-dotenv: Optional, but simplifies loading environment variables like your table name
Step 2: Full Code Implementation
Here's the Python equivalent of your Node.js code, with comments linking back to your original logic:
import boto3 import pytz from datetime import datetime, timedelta import os from dotenv import load_dotenv # Load environment variables (skip this if you're setting variables directly) load_dotenv() # Initialize DynamoDB's DocumentClient equivalent dynamodb = boto3.resource('dynamodb') table = dynamodb.Table(os.getenv('TableName')) # Match the Pacific/Auckland timezone from your Node.js code auckland_tz = pytz.timezone('Pacific/Auckland') # Calculate current time and 24 hours prior (in Auckland timezone) now = datetime.now(auckland_tz) yesterday = now - timedelta(hours=24) # Format dates to ISO string (matches the output of moment().format()) now_str = now.isoformat() yesterday_str = yesterday.isoformat() # Build Scan parameters - identical structure to your Node.js params scan_params = { 'FilterExpression': '#ts between :val1 and :val2', 'ExpressionAttributeNames': { '#ts': 'timeStamp' # Alias for your timestamp attribute }, 'ExpressionAttributeValues': { ':val1': yesterday_str, ':val2': now_str } } # Execute the Scan operation response = table.scan(**scan_params) items = response['Items'] # Handle pagination (critical! DynamoDB only returns ~1MB of data per Scan call) while 'LastEvaluatedKey' in response: response = table.scan( ExclusiveStartKey=response['LastEvaluatedKey'], **scan_params ) items.extend(response['Items']) # Use your results however you need print(f"Retrieved {len(items)} items from the last 24 hours (Auckland time)")
Key Notes to Match Your Original Logic
- Timezone Consistency: We use
pytzto lock into Pacific/Auckland time, just like yourmoment().tz()call.datetime.now(auckland_tz)gives us a timezone-aware datetime object to avoid offset errors. - Date Formatting:
isoformat()produces the same ISO 8601 string format asmoment().format(), ensuring DynamoDB can correctly compare yourtimeStampattribute. - Scan Parameters: The
FilterExpression,ExpressionAttributeNames, andExpressionAttributeValuesmirror your Node.js code exactly—no changes to the core query logic. - Pagination: I added pagination handling because DynamoDB's Scan has a 1MB per-request limit. Your Node.js code might have omitted this, but it's essential for production use if you have large datasets.
Edge Cases to Consider
- If your
timeStampstores Unix timestamps instead of ISO strings, replace the date formatting withyesterday.timestamp()andnow.timestamp()to get numeric values. - Ensure your AWS credentials are configured correctly (via environment variables,
~/.aws/credentials, or IAM roles if running on AWS services like EC2/EKS).
内容的提问来源于stack exchange,提问作者NeuroWinter




