Quick Start Guide
This guide walks you through creating your first Da Vinci application.
Prerequisites
Before starting, ensure you have:
Python 3.11+ installed (Python 3.12+ required for CDK)
Docker installed and running (required for Lambda function packaging)
AWS account with appropriate permissions (DynamoDB, Lambda, CloudFormation)
AWS credentials configured (
aws configure)AWS CDK CLI installed (
npm install -g aws-cdk)Da Vinci packages installed (see Installation)
Creating Your First Application
Step 1: Define a DynamoDB Table
Create a file called tables.py to define your DynamoDB tables:
from da_vinci.core.orm.table_object import (
TableObject,
TableObjectAttribute,
TableObjectAttributeType,
)
class UserTable(TableObject):
"""User table for storing user information"""
table_name = "users"
partition_key_attribute = TableObjectAttribute(
name="user_id",
attribute_type=TableObjectAttributeType.STRING,
description="Unique user identifier",
)
attributes = [
TableObjectAttribute(
name="email",
attribute_type=TableObjectAttributeType.STRING,
description="User email address",
),
TableObjectAttribute(
name="name",
attribute_type=TableObjectAttributeType.STRING,
description="User display name",
),
TableObjectAttribute(
name="created_at",
attribute_type=TableObjectAttributeType.DATETIME,
description="When the user was created",
),
]
Step 2: Create Application Logic
Create a file called user_service.py for your business logic:
from datetime import UTC, datetime
from da_vinci.core.orm.client import TableClient
from tables import UserTable
class UserService:
def __init__(self):
self.table_client = TableClient(UserTable)
def create_user(self, user_id: str, email: str, name: str):
"""Create a new user"""
user = UserTable(
user_id=user_id,
email=email,
name=name,
created_at=datetime.now(UTC),
)
self.table_client.put(user)
return user
def get_user(self, user_id: str):
"""Retrieve a user by ID"""
return self.table_client.get(user_id)
def list_users(self):
"""List all users"""
return list(self.table_client.scan())
Step 3: Create Table Stack
Create a file called table_stack.py for your DynamoDB table stack:
from constructs import Construct
from da_vinci_cdk.stack import Stack
from da_vinci_cdk.constructs.dynamodb import DynamoDBTable
from tables import UserTable
class UserTableStack(Stack):
"""Stack that provisions the User DynamoDB Table"""
def __init__(
self,
app_name: str,
deployment_id: str,
scope: Construct,
stack_name: str
) -> None:
super().__init__(
app_name=app_name,
deployment_id=deployment_id,
scope=scope,
stack_name=stack_name,
)
self.table = DynamoDBTable.from_orm_table_object(
table_object=UserTable,
scope=self,
)
Step 4: Deploy Infrastructure with CDK
Create a file called app.py for your CDK infrastructure:
from os.path import dirname, abspath
from da_vinci_cdk.application import Application
from table_stack import UserTableStack
# Create application
app = Application(
app_name="my-app",
deployment_id="dev",
app_entry=abspath(dirname(__file__)),
)
# Add table stack to application
app.add_uninitialized_stack(UserTableStack)
# Synthesize CDK stacks
app.synth()
Note
Naming Requirements: app_name and deployment_id must use only alphanumeric characters and hyphens.
They must start with a letter. Do not use underscores, as CloudFormation stack names follow the pattern
/^[A-Za-z][A-Za-z0-9-]*$/.
Step 5: Deploy to AWS
Deploy your application to AWS using the CDK CLI:
# Bootstrap CDK (first time only)
cdk bootstrap
# Deploy the application
cdk deploy --all
Step 6: Use Your Application
Now you can use your application:
from user_service import UserService
# Create service instance
service = UserService()
# Create a user
user = service.create_user(
user_id="user-123",
email="alice@example.com",
name="Alice Smith"
)
# Retrieve the user
retrieved_user = service.get_user("user-123")
print(f"User: {retrieved_user.name} ({retrieved_user.email})")
# List all users
users = service.list_users()
for user in users:
print(f"- {user.name}")
Summary
In these steps, you:
Defined a DynamoDB table using Da Vinci’s table object system
Created business logic using the table client for CRUD operations
Deployed infrastructure automatically from your table definitions
Used your application with type-safe table objects
Key Concepts
- Table Objects
Table objects define both your data model and drive infrastructure generation. They provide type safety and eliminate boilerplate for DynamoDB operations.
- Table Client
The table client provides methods for interacting with DynamoDB tables:
put(),get(),scan(),query(), and more.- Application
The CDK Application construct manages your infrastructure deployment, automatically creating resources from your table definitions.
Next Steps
Now that you’ve built your first application, explore:
Architecture - Understand how Da Vinci components work together
Examples - See more complex examples
Core API Reference - Dive into the core API reference
CDK API Reference - Learn about CDK constructs and patterns
Common Patterns
Adding Indexes
class UserTable(TableObject):
table_name = "users"
partition_key_attribute = "user_id"
# Add a GSI for querying by email
global_secondary_indexes = [
{
"index_name": "email_index",
"partition_key": "email",
}
]
Querying with Indexes
# Query by email using GSI
users = table_client.query(
index_name="email_index",
partition_key_value="alice@example.com"
)
Using Scan Filters
from da_vinci.core.orm.client import TableScanDefinition
# Scan with filter
scan_def = TableScanDefinition(UserTable)
scan_def.add("email", "contains", "@example.com")
users = table_client.scan(scan_definition=scan_def)
Troubleshooting
- Table Not Found
Ensure you’ve deployed your infrastructure with
cdk deploy --alland that your AWS credentials are configured correctly.- Import Errors
Make sure both
da-vinciandda-vinci-cdkare installed in your environment.- Permission Errors
Ensure your AWS credentials have permissions to create DynamoDB tables and other required resources.