Quickstart Guide ================ This guide will walk you through the basics of using Tapestry to interact with SurrealDB. Basic Setup ----------- First, make sure you have SurrealDB running and Tapestry installed. Then, let's create a simple application. Connecting to SurrealDB ----------------------- Start by establishing a connection to your SurrealDB instance: .. code-block:: python from surrealdb import Surreal async def get_db(): db = Surreal("ws://localhost:8000/rpc") await db.connect() await db.signin({"user": "root", "pass": "root"}) await db.use("myapp", "myapp") return db Defining Models --------------- Tapestry uses Python classes to define your database schema. Let's create a simple blog application: **Node Models** Nodes represent entities in your database: .. code-block:: python from tapestry import Node from datetime import datetime from typing import Optional class Author(Node): """Represents a blog author.""" username: str email: str full_name: str bio: Optional[str] = None joined_date: datetime class Post(Node): """Represents a blog post.""" title: str content: str published: bool = False created_at: datetime updated_at: datetime **Edge Models** Edges represent relationships between nodes: .. code-block:: python from tapestry import Edge class Wrote(Edge): """Links an author to their posts.""" in_: Post out_: Author published_at: datetime Creating Records ---------------- Create instances of your models and save them to the database: .. code-block:: python import asyncio from datetime import datetime async def create_data(): db = await get_db() # Create an author alice = Author( username="alice", email="alice@example.com", full_name="Alice Smith", bio="Tech writer and developer", joined_date=datetime.now() ) await alice.create(db) print(f"Created author: {alice.id}") # Create a post post = Post( title="Getting Started with Tapestry", content="Tapestry makes working with SurrealDB a breeze...", published=True, created_at=datetime.now(), updated_at=datetime.now() ) await post.create(db) print(f"Created post: {post.id}") # Create relationship wrote = Wrote( in_=post, out_=alice, published_at=datetime.now() ) await wrote.relate(db) print(f"Created relationship: {wrote.id}") # Run it asyncio.run(create_data()) Querying Records ---------------- Fetch records from the database: **Select All** .. code-block:: python async def get_all_authors(): db = await get_db() # Get all authors authors = await Author.select(db) for author in authors: print(f"{author.username}: {author.email}") **Select by ID** .. code-block:: python from tapestry.utils import RecordID async def get_author_by_id(): db = await get_db() # Get specific author author_id = RecordID("author:alice") alice = await Author.select(db, author_id) print(alice.full_name) **Filter Records** .. code-block:: python async def get_published_posts(): db = await get_db() # Query with conditions query = "SELECT * FROM post WHERE published = true" posts = await db.query(query) # Deserialize to Post objects from tapestry import Base posts = [Base.deserialize_record(p) for p in posts[0]['result']] return posts Updating Records ---------------- Update existing records: .. code-block:: python async def update_post(): db = await get_db() # Get the post post_id = RecordID("post:123") post = await Post.select(db, post_id) # Update fields post.title = "Updated Title" post.updated_at = datetime.now() # Save changes await post.update(db) print("Post updated!") Deleting Records ---------------- Delete records from the database: .. code-block:: python async def delete_post(): db = await get_db() # Get the post post_id = RecordID("post:123") post = await Post.select(db, post_id) # Delete it await post.delete(db) print("Post deleted!") Schema Generation ----------------- Tapestry can automatically generate SurrealQL schema from your models: .. code-block:: python from tapestry import Base # Generate schema for all registered models schema = Base.generate_schema() print(schema) # Apply schema to database async def setup_schema(): db = await get_db() schema = Base.generate_schema() await db.query(schema) print("Schema created!") asyncio.run(setup_schema()) Complete Example ---------------- Here's a complete example putting it all together: .. code-block:: python import asyncio from datetime import datetime from typing import Optional from surrealdb import Surreal from tapestry import Node, Edge, Base from tapestry.utils import RecordID # Define models class Author(Node): username: str email: str full_name: str bio: Optional[str] = None joined_date: datetime class Post(Node): title: str content: str published: bool = False created_at: datetime updated_at: datetime class Wrote(Edge): in_: Post out_: Author published_at: datetime async def main(): # Connect to database db = Surreal("ws://localhost:8000/rpc") await db.connect() await db.signin({"user": "root", "pass": "root"}) await db.use("blog", "blog") # Setup schema schema = Base.generate_schema() await db.query(schema) print("✓ Schema created") # Create author alice = Author( username="alice", email="alice@example.com", full_name="Alice Smith", bio="Tech enthusiast", joined_date=datetime.now() ) await alice.create(db) print(f"✓ Created author: {alice.username}") # Create post post = Post( title="My First Post", content="Hello, SurrealDB!", published=True, created_at=datetime.now(), updated_at=datetime.now() ) await post.create(db) print(f"✓ Created post: {post.title}") # Create relationship wrote = Wrote( in_=post, out_=alice, published_at=datetime.now() ) await wrote.relate(db) print(f"✓ Linked author to post") # Query all authors authors = await Author.select(db) print(f"✓ Found {len(authors)} author(s)") # Cleanup await db.close() if __name__ == "__main__": asyncio.run(main()) Next Steps ---------- Now that you know the basics, you can: - Explore the :doc:`api/index` for detailed documentation - Learn about advanced querying and graph traversals - Check out type hints and validation features - Understand how to optimize your schema Tips & Best Practices ---------------------- **Use Type Hints** Always use type hints for better IDE support and validation: .. code-block:: python class User(Node): name: str # Required age: int bio: Optional[str] = None # Optional with default **Initialize Datetime Fields** Use ``datetime.now()`` for timestamp fields: .. code-block:: python from datetime import datetime user = User( name="Alice", age=30, created_at=datetime.now() ) **Handle Async Properly** Always use ``await`` with database operations: .. code-block:: python # Correct user = await User.select(db, user_id) # Wrong - will not work user = User.select(db, user_id) **Close Connections** Use context managers or remember to close connections: .. code-block:: python async with Surreal("ws://localhost:8000/rpc") as db: await db.signin({"user": "root", "pass": "root"}) # Your code here # Connection automatically closed **Generate Schema First** Always set up your schema before inserting data: .. code-block:: python schema = Base.generate_schema() await db.query(schema) # Now you can create records