Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/3mcloud/falcano
A pythonic interface to Amazon's DynamoDB for single-table design
https://github.com/3mcloud/falcano
aws dynamodb python single-table-design
Last synced: about 2 months ago
JSON representation
A pythonic interface to Amazon's DynamoDB for single-table design
- Host: GitHub
- URL: https://github.com/3mcloud/falcano
- Owner: 3mcloud
- License: mit
- Created: 2020-07-13T18:00:11.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-12-15T17:50:05.000Z (about 3 years ago)
- Last Synced: 2024-11-02T02:17:40.191Z (2 months ago)
- Topics: aws, dynamodb, python, single-table-design
- Language: Python
- Homepage:
- Size: 249 KB
- Stars: 59
- Watchers: 9
- Forks: 10
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Falcano
A Pythonic interface for Amazon's DynamoDB that supports Python 3 and [single-table design](https://www.alexdebrie.com/posts/dynamodb-single-table/) based on [PynamoDB](https://github.com/pynamodb/PynamoDB).
## Installation
```bash
pip install falcano
```## Basic Usage
Basic usage is nearly identical to `PynamoDB`. `Meta` must inherit from `Model.Meta` and `Type` must be defined for every model.
Create a model that describes a model in your table.
```python
from falcano.model import Model
from falcano.attributes import UnicodeAttributeclass User(Model):
'''
A DynamoDB User
'''
class Meta(Model.Meta):
table_name = 'dynamodb-user'
billing_mode = 'PAY_PER_REQUEST'
email = UnicodeAttribute(null=True)
first_name = UnicodeAttribute(range_key=True)
last_name = UnicodeAttribute(hash_key=True)
Type = UnicodeAttribute(default='user')
```Create the table if needed:
```python
User.create_table(billing_mode='PAY_PER_REQUEST')
```Create a new user:
```python
user = User('John', 'Denver')
user.email = '[email protected]'
user.save()
```Now, search your table for all users with a last name of 'Denver' and whose first name begins with 'J':
```python
for user in User.query('Denver', User.first_name.startswith('J')):
print(user.first_name)
```Examples of ways to query your table with filter conditions:
```python
for user in User.query('Denver', User.email.eq('[email protected]')):
print(user.first_name)
for user in User.query('Denver', User.email=='[email protected]'):
print(user.first_name)
```Retrieve an existing user:
```python
try:
user = User.get('John', 'Denver')
print(user)
except User.DoesNotExist:
print('User does not exist')
```## Advanced Usage
Indexes? No problem:
```python
from falcano.model import Model
from falcano.indexes import GlobalSecondaryIndex, AllProjection
from falcano.attributes import NumberAttribute, UnicodeAttributeclass ViewIndex(GlobalSecondaryIndex):
class Meta:
billing_mode = 'PAY_PER_REQUEST'
projection = AllProjection()
view = NumberAttribute(default=0, hash_key=True)class TestModel(Model):
class Meta(Model.Meta):
table_name = 'TestModel'
forum = UnicodeAttribute(hash_key=True)
thread = UnicodeAttribute(range_key=True)
view = NumberAttribute(default=0)
Type = UnicodeAttribute(default='test')
view_index = ViewIndex()
```Now query the index for all items with 0 views:
```python
for item in TestModel.view_index.query(0):
print(f'Item queried from index: {item}')
```It's simple!
Want to use DynamoDB local? Add a `host` name attribute and specify your local server.
```python
from falcano.models import Model
from falcano.attributes import UnicodeAttributeclass User(Model):
'''
A DynamoDB User
'''
class Meta(Model.Meta):
table_name = 'dynamodb-user'
host = 'http://localhost:8000'
email = UnicodeAttribute(null=True)
first_name = UnicodeAttribute(range_key=True)
last_name = UnicodeAttribute(hash_key=True)
Type = UnicodeAttribute(default='user')
```## Single-Table Design Usage
Want to follow single-table design with an index and rename the `Type` attribute? No problem:
```python
from falcano.model import Model
from falcano.indexes import GlobalSecondaryIndex, AllProjection
from falcano.attributes import NumberAttribute, UnicodeAttributeclass TypeIndex(GlobalSecondaryIndex):
class Meta:
index_name = 'Type'
billing_mode = 'PAY_PER_REQUEST'
projection = AllProjection()
Kind = UnicodeAttribute(default=0, hash_key=True)class BaseModel(Model):
class Meta(Model.Meta):
table_name = 'single_table'
# use the Kind attribute in place of Type for deserialization
model_type = 'Kind'
PK = UnicodeAttribute(hash_key=True)
SK = UnicodeAttribute(range_key=True)
TypeIndex = TypeIndex()class User(BaseModel):
email = UnicodeAttribute(null=True)
Kind = UnicodeAttribute(default='user')class Team(BaseModel):
owner = UnicodeAttribute(null=True)
Kind = UnicodeAttribute(default='team')
```## Features
- Python >= 3.8 support
- Use of `Table` boto3 resource
- DynamoDB API `conditions` objects
- Auto-Typing
- An ORM-like interface with query and scan filters
- Compatible with DynamoDB Local
- Support for Unicode, Binary, JSON, Number, Set, and UTC Datetime attributes
- Support for Global and Local Secondary Indexes
- Automatic pagination for bulk operations(?)
- Complex queries
- Multiple models per table and deserialization into objects## Features not yet implemented
- Provides iterators for working with queries, scans, that are automatically - paginated
- Iterators for working with Query and Scan operations
- Supports the entire DynamoDB API
- Full table backup/restore
- Batch operations with automatic pagination